質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Q&A

1回答

7179閲覧

Python - Flask socketIOで更新すると通信が重複する問題

starrow1103

総合スコア137

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

0グッド

1クリップ

投稿2017/05/11 01:10

編集2017/05/11 02:56

開発環境

MacOS Sierra
バージョン:Python 3.6
フレームワーク:Flask

やっていること

ページを起動すると、websocketを使いサーバー側から1秒に一回数字を受け取り、リアルタイムで表示させる。

###app.py

python

1from flask import Flask,render_template, session, request,redirect 2from flask_socketio import SocketIO, emit, disconnect 3 4async_mode = None 5 6app = Flask(__name__) 7app.config['SECRET_KEY'] = 'hoge' 8socketio = SocketIO(app, async_mode=async_mode) 9 10# 毎秒1ずつカウントし、my_responseにemitする 11def background(): 12 count = 0 13 while True: 14 socketio.sleep(1) 15 count += 1 16 socketio.emit('my_response', {'data': count}, namespace='/test') 17 18@app.route('/') 19def index(): 20 socketio.start_background_task(target=background) 21 return render_template('index.html') 22 23if __name__ == '__main__': 24 socketio.run(app, host='127.0.0.1', port=5000, debug=True)

###index.html
layout.htmlは割愛します

html

1{% extends "layout.html" %} 2{% block script %} 3<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script> 4<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script> 5<script type="text/javascript" charset="utf-8"> 6 $(document).ready(function() { 7 namespace = '/test'; 8 var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace); 9 var title = document.title; 10 11 socket.on('my_response', function(msg) { 12 $('#field').append(msg.data); 13 }); 14 15 }); 16</script> 17{% endblock %} 18 19{% block body %} 20 21<section id="field"></section> 22{% endblock %}

これで以下の画像のように、毎秒1ずつ数字が追加され表示されるのですが、
イメージ説明

困っていること

ページをリロードすると、複数のソケット接続(?)が発生するためか、リロードした回数分おかしな表示が増えていってしまいます。

例)カウントが15の時点でリロードすると、
1回目の接続の続き:15,16,17...
2回目で発生した接続:1,2,3...
この両方が重なり、以下のように表示されてしまいます。
115216317...

小生、websocketの知識が乏しく、Javascriptもいじっては修正の繰り返しでなんとかやっています。

リロードすると、接続状態をリセットし、カウントを初期から単一接続で行う
方法がわからず困っています。

わかりにくい説明&ニッチな問題で申し訳ありませんが、どなたかわかる方がいらっしゃいましたら、ご教授いただきたく思います。

よろしくお願いいたします。

追記:やってみたこと

更新した場合に「/hoge」にリダイレクトさせ、以降はそちらのみのアクセスに強制・・・みたいなことをやれば、start_backgroundの回避はできましたが、根本的な解決にはなっていません。

python

1@app.route('/') 2def index(): 3 socketio.start_background_task(target=background) 4 return render_template('index.html') 5 6@app.route('/hoge') 7def index(): 8 return render_template('index.html')

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

リロードすると、websocketのコネクションも別のものになります。
そのため、貴殿が提示された解決方法も一つの手法かと思います。
あるいは、一回のコネクションでセッションを取得し、リロード時にはきちんと終了処理をした上で、最新のセッションのみを対象に処理を行うのが手っ取り早いかもしれません。

投稿2017/05/11 04:11

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/05/11 04:17

回答ありがとうございます。 >コネクションでセッションを取得し、リロード時にはきちんと終了処理をした上で、最新のセッションのみを対象に処理を行う これができたら良いのですが、ドキュメントを読んでもよくわからず・・・ おそらく、request.sid等を引き継げば良いのでしょうが、ご存知ないでしょうか。 当面の間は、リダイレクトの方向で進めていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問