SSEメッセージを送信するピラミッドアプリケーションがあります。基本的に次のように機能します。
def message_generator():
for i in range(100):
print("Sending message:" + str(i))
yield "data: %s\n\n" % json.dumps({'message': str(i)})
time.sleep(random.randint(1, 10))
@view_config(route_name='events')
def events(request):
headers = [('Content-Type', 'text/event-stream'),
('Cache-Control', 'no-cache')]
response = Response(headerlist=headers)
response.app_iter = message_generator()
return response
/ eventsを参照すると、イベントが表示されます。別のページに移動するとイベントが停止し、ブラウザを閉じるとイベントが停止します。
この問題は、たとえば、/ eventsにいて、コンピューターの電源を切った場合に発生します。サーバーはクライアントが失われたことを認識せず、message_generatorはvoidにメッセージを送信し続けます。
このページの内容:サーバー送信イベントの概要は次のとおりです。
...サーバーはこれを検出し(クライアントが停止したとき)、クライアントがイベントをリッスンしなくなったため、それ以上のイベントの送信を停止する必要があります。サーバーがこれを行わない場合、サーバーは基本的にイベントをvoidに送信します。
Pyramidでこれを検出する方法はありますか?で試しました
request.add_finished_callback()
しかし、このコールバックはで呼び出されるようです
return response
サーバーを起動するためにgeventでGunicornを使用します。
どんなアイデアでも大歓迎です
PEP 3333から:
ジェネレーターまたは他のカスタムイテレーターを返すアプリケーションは、サーバーによって早期に閉じられる可能性があるため、イテレーター全体が消費されると想定しないでください。
基本的に、WSGIサーバーは、クライアントが切断さclose()
れたapp_iter
ときにメソッドを呼び出す必要があります(例のように、すべてのジェネレーターがこれを自動的にサポートします)。ただし、サーバーはそれを行う必要はなく、多くのWSGIサーバーはそうではないようです。たとえば、gunicorn(私は独自に検証していません)について言及しましたが、ウェイトレスも検証していません。その結果、ウェイトレスで[1]を開き、修正に取り組んでいます。WSGI環境でのストリーミング応答は、せいぜい不安定であり、通常はサーバーに依存します。たとえば、ウェイトレスではsend_bytes=0
、応答データがバッファリングされないように設定する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加