9

複数のクライアントがサーバー送信イベント ストリームに接続しようとしています/stream。これは 1 つのクライアントで機能しますが、それ以上のクライアントを接続しようとすると、新しいクライアントがデータを待機して無期限にブロックされます。さらにデータを送信すると、最初のクライアントにのみ送信され、他のクライアントには送信されません。

ここに私の問題を示す小さなスニペットがあります:

import flask
import time

app = flask.Flask(__name__)

def event_stream():
    for i in xrange(9999):
        yield "data: %d\n\n" % i
        time.sleep(1)

@app.route("/stream", methods=[ "GET" ])
def stream():
    return flask.Response(
        event_stream(),
        mimetype="text/event-stream"
    )

次に、これを で実行しgunicorn --worker-class=gevent -w 4 -t 99999 app:appます。単一のクライアントに対しては機能しますが、発行時に他のクライアントはブロックされGET /streamます。

ブロックの原因は何ですか?どうすれば修正できますか?

もう少しデバッグしたところ、奇妙な結果が得られました。この手順を実行すると、次のようになります。

  • クライアント 1 を起動します (クライアント 1 のみがデータを受信します)。
  • クライアント 2 の起動 (クライアント 1 のみがデータを受信)
  • クライアント 3 の起動 (クライアント 1 のみがデータを受信)
  • クライアント 4 の起動 (クライアント 1 のみがデータを受信)
  • クライアント 1 を再起動します (4 つのクライアントすべてが突然同時にデータの受信を開始します)。
4

2 に答える 2

3

これは、私がテストしていた Chromium Web ブラウザーと関係があることがわかりました。何らかの理由で、最初のリクエストが完了するまでリクエストを保留します。またはシークレットブラウザセッションを使用するcurlと、複数のセッションを同時に実行できました。これは、私の問題が実際には存在しないことを意味します。Chromium が同じリソースへの同時リクエストを処理する方法が原因で、そのように見えるだけです。

Chromium がこのように振る舞う理由はよくわかりません。奇妙に思えます。いずれにせよ、これは実際の問題ではなく、私のブラウザによって認識されているだけです。

于 2013-06-24T08:21:45.747 に答える
2

Firefoxでも同様の結果が得られました(コメントで指摘したように)、メインブロックでgunicornの代わりにWSGIServerを使用するように切り替え、すべてが機能し、タイムアウトがなくなりました(WSGIServerはワーカーをタイムアウトしませんが、gunicornはタイムアウトするため)これは答えとして追加する価値があると思いました。

これを追加:

if __name__ == '__main__':
http_server = WSGIServer(('127.0.0.1', 8001), app)
http_server.serve_forever()

それからただする

python app.py

[Chris のコマンド ラインを使用してタイムアウトを 99999 に設定していれば、30 秒後にタイムアウトすることはなかったでしょうが、ずっと後に発生していたでしょう]

于 2013-07-19T02:55:31.970 に答える