【问题标题】:Server sent events with Flask/Redis: how can more than one client view a stream?服务器使用 Flask/Redis 发送事件:多个客户端如何查看流?
【发布时间】:2013-06-20 00:27:11
【问题描述】:

我有多个客户端尝试连接到服务器发送的事件流/stream。这适用于单个客户端,但尝试连接更多客户端会导致新客户端无限期地阻塞等待数据。如果我发送更多数据,它只会发送给第一个客户端,而不会发送给其他客户端。

这是一个说明我的问题的小sn-p:

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个客户端突然同时开始接收数据)

【问题讨论】:

标签: python flask blocking server-sent-events


【解决方案1】:

事实证明,这与我正在测试的 Chromium 网络浏览器有关。由于某种原因,它会在第一个请求完成之前阻止发出请求。使用curl 或隐身浏览器会话允许多个会话同时运行。这意味着我的问题在现实中并不存在,只是因为 Chromium 处理对同一资源的同时请求的方式而出现的问题。

我不太清楚 Chromium 为什么会这样,这看起来很奇怪。无论哪种方式,这都不是真正的问题,只是我的浏览器感知到的问题。

【讨论】:

  • 我在 OSX 上的 Firefox 中得到了类似的结果。如果我从第二个选项卡进行相同的请求,它会等到第一个挂起(大约 30 秒后)然后启动。启动私人窗口允许两个会话同时运行。
  • 这也影响 Chrome 35 和 Opera 22,但不影响 Firefox 29。全部在 Windows 上。
  • 观察到同样的问题,为什么所有这些浏览器都这样做呢?我以为我的服务器代码有问题
【解决方案2】:

我在 Firefox 中得到了类似的结果(正如我在 cmets 中所指出的那样),然后我切换到在主块中使用 WSGIServer 而不是 gunicorn 并且一切正常,超时消失了(因为 WSGIServer 不会使其工作人员超时但 gunicorn确实)所以我认为这值得添加作为答案。

添加这个:

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

那就做吧

python app.py

[如果我使用 Chris 的命令行并将超时设置为 99999,我不会在 30 秒后出现超时,但会晚得多]

【讨论】:

  • 这不是我的问题,但我同意它可能会出现在其他情况下。谢谢!
  • 除了 curl 之外,你有没有看到除了 Chromium 之外的任何东西都可以使用它?
  • 不,我没有。我想这对于任何想要进一步调查的人来说应该很容易重现:-)
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多