2014-03-06 42 views
0

我正尝试使用Flask来提供SSE请求,但是我的客户端只在我的生成器函数停止/连接关闭后才接收事件。为什么我的生成器阻止Flask发送SSE响应?

这里是我已经能够生产证明这一点最简单的再现:

#!/usr/bin/env python 

from flask import Flask, Response 
from time import sleep 

def stream(): 
    n = 10 
    while n > 0: 
     yield "data: hi\n\n" 
     sleep(0.5) 
     n = n - 1 

app = Flask(__name__) 

@app.route("/events") 
def streamSessionEvents(): 
    return Response(
     stream(), 
     mimetype="text/event-stream" 
    ) 

app.run(debug=True, threaded=True) 

这里是我的测试客户端:

<!doctype html> 
<html> 
<head> 
    <script> 
     var source = new EventSource(
      "/events" 
     ); 
     source.onmessage = function(event) 
     { 
      console.log(event); 
     }; 
    </script> 
</head> 
<body> 
</body> 
</html> 

流()发生器会产生十大事件,然后返回(我故意这样做是为了证明问题,理想情况下发电机将永远持续运行),此时连接将被丢弃。客户端页面在此之前不记录任何内容,然后它吐出所有十个事件(如果我没有stream()中的计数器变量,那么该页面永远不会获得任何事件)。

我还没有使用Python或Flask很多,这让我非常困惑,我不能看到我对网络上其他例子的不同做法。非常感谢任何帮助。

回答

0

两件事情可能会干扰:

  1. 你必须debug设置为True,它安装中间件(特别是Werkzeug debugger)可能破坏流。

    Flask streaming patterns documentation

    不过,请注意一些WSGI中间件可能打破流,所以要小心有与剖析,你可能已经启用了其他的事情调试环境。

    然而,即使用curl或Chrome与瓶0.10.1和WERKZEUG 0.9.4测试代码中,我看到了data: hi反应来通过适当的流,不管debug标志设置的。换句话说,您的代码可以正确使用最新版本的Flask堆栈。

  2. EventSource流受same-origin policy限制。如果您没有从相同的主机和端口加载HTML页面,则将拒绝对您的Flask服务器的请求。

    添加在烧瓶服务器测试页面的源代码在一个单独的路线为我工作:

    @app.route('/') 
    def index(): 
        return '''\ 
    <!doctype html> 
    <html> 
    <head> 
        <script> 
         var source = new EventSource(
          "/events" 
         ); 
         source.onmessage = function(event) 
         { 
          console.log(event); 
         }; 
        </script> 
    </head> 
    <body> 
    </body> 
    </html> 
    ''' 
    
+0

“......你的代码与最新版本的瓶堆的正常工作”我只是在我的家用机器上测试过,并且它完美地工作。尴尬。我将不得不在明天早上推动我的工作机器来研究发生了什么。非常感谢您的帮助。 –

相关问题