7

誰かがページに接続すると、ブラウザに 10 秒ごとにエミットを送信する「キープアライブ」Websocket スレッドを作成しようとしていますが、エラーが発生し、それを回避する方法がわかりません。

これを機能させる方法についてのアイデアはありますか?

そして、「切断」が送信されたら、どうすればこのスレッドを強制終了できますか?

ありがとう!

@socketio.on('connect', namespace='/endpoint')
def test_connect():
    emit('my response', {'data': '<br>Client thinks i\'m connected'})

    def background_thread():
        """Example of how to send server generated events to clients."""
        count = 0
        while True:
            time.sleep(10)
            count += 1
            emit('my response', {'data': 'websocket is keeping alive'}, namespace='/endpoint')

    global thread
    if thread is None:
        thread = Thread(target=background_thread)
        thread.start()
4

1 に答える 1

10

バックグラウンド スレッドにダイレクト メッセージを送信しているため、クライアントが誰であるかを知る必要がある方法でバックグラウンド スレッドを作成しました。そのため、バックグラウンド スレッドはリクエスト コンテキストにアクセスできる必要があります。copy_current_request_contextFlask では、デコレータを使用して現在のリクエスト コンテキストのコピーをスレッドにインストールできます。

@copy_current_request_context
def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        time.sleep(10)
        count += 1
        emit('my response', {'data': 'websocket is keeping alive'}, namespace='/endpoint')

いくつかのメモ:

  • クライアントに送り返すときに名前空間を設定する必要はありません。デフォルトでは、emit呼び出しはクライアントが使用する名前空間と同じになります。リクエスト コンテキストの外部でメッセージをブロードキャストまたは送信する場合は、名前空間を指定する必要があります。
  • 設計では、接続するクライアントごとに個別のスレッドが必要になることに注意してください。すべてのクライアントにブロードキャストするバックグラウンド スレッドを 1 つ持つ方が効率的です。例については、Github リポジトリにあるサンプル アプリケーションを参照してください: https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example

クライアントが切断されたときにスレッドを停止するには、任意のマルチスレッド メカニズムを使用して、終了する必要があることをスレッドに知らせることができます。これは、たとえば、切断イベントで設定したグローバル変数にすることができます。実装が簡単であまり優れていない代替手段はemit、クライアントが離れたときに例外が発生するのを待ち、それを使用してスレッドを終了することです。

于 2014-12-01T08:32:35.180 に答える