简体   繁体   English

服务器使用Flask / Redis发送事件:多个客户端如何查看流?

[英]Server sent events with Flask/Redis: how can more than one client view a stream?

I have multiple clients trying to connect to a server sent events stream at /stream . 我有多个客户端尝试连接到/stream的服务器发送事件/stream This works with a single client, but attempting to connect any more clients results in the new client becoming indefinitely blocked waiting for data. 这适用于单个客户端,但尝试连接任何其他客户端会导致新客户端无限期地阻塞等待数据。 If I send more data, it only goes to the first client, and no others. 如果我发送更多数据,它只会发送给第一个客户端,而不会发送给其他客户端。

Here is a small snippet that illustrates my problem: 这是一个小片段,说明了我的问题:

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"
    )

I then run this with gunicorn --worker-class=gevent -w 4 -t 99999 app:app . 然后我用gunicorn --worker-class=gevent -w 4 -t 99999 app:app运行gunicorn --worker-class=gevent -w 4 -t 99999 app:app It works for a single client, but any others get blocked when issuing GET /stream . 它适用于单个客户端,但在发出GET /stream时会阻止任何其他客户端。

What is the cause of the block, and how should I fix it? 阻止的原因是什么,我该如何解决?

I debugged a little more and got some strange results. 我调试了一点,得到了一些奇怪的结果。 If I do this procedure, then this happens: 如果我执行此过程,则会发生以下情况:

  • Start client 1 (only client 1 receiving data) 启动客户端1(仅客户端1接收数据)
  • Start client 2 (only client 1 receiving data) 启动客户端2(仅客户端1接收数据)
  • Start client 3 (only client 1 receiving data) 启动客户端3(仅客户端1接收数据)
  • Start client 4 (only client 1 receiving data) 启动客户端4(仅客户端1接收数据)
  • Restart client 1 (all 4 clients suddenly start receiving data at the same time) 重启客户端1(所有4个客户端突然开始同时接收数据)

It turns out that this is something to do with the Chromium web browser, where I was testing. 事实证明,这与我正在测试的Chromium Web浏览器有关。 It holds back on making the request until the first one completes, for some reason. 由于某种原因,它会在第一个请求完成之前停止发出请求。 Using curl , or an incognito browser session allowed multiple sessions to run at the same time. 使用curl或隐身浏览器会话允许多个会话同时运行。 This means that my problem doesn't really exist in reality, it just appears that way because of the way that Chromium handles simultaneous requests to the same resource. 这意味着我的问题实际上并不存在,只是因为Chromium处理对同一资源的同时请求的方式。

I'm not sure quite why Chromium behaves this way, it seems weird. 我不确定Chromium为什么会这样,这看起来很奇怪。 Either way, this isn't a real problem, only a perceived one by my browser. 无论哪种方式,这不是一个真正的问题,只有我的浏览器感知到的问题。

I was getting similar results in Firefox (as I noted in the comments) then I switched to using WSGIServer in the main block instead of gunicorn and everything works, the timeout is gone (because WSGIServer doesn't timeout its workers but gunicorn does) so I thought this made it worth adding as an answer. 我在Firefox中得到了类似的结果(正如我在评论中提到的那样)然后我切换到在主要块中使用WSGIServer而不是gunicorn并且一切正常,超时已经消失(因为WSGIServer不会超时其工作人员但是gunicorn会这样做)所以我认为这值得添加作为答案。

Add this: 添加这个:

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

Then just do 然后就做

python app.py

[I would not have had a timeout after 30s if I had used Chris' command line and set timeout to 99999 but there would have been much later] [如果我使用了Chris的命令行并将超时设置为99999,那么30秒后我就不会超时了,但之后会有更长的时间]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM