为什么我的发电机阻止Flask发送SSE响应?

时间:2014-03-06 18:41:16

标签: python flask generator

我正在尝试使用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()生成器将生成十个事件然后返回(我故意这样做是为了演示问题,理想情况下,生成器将永远继续),此时连接被删除。客户端页面在此之前没有记录任何内容,然后它会吐出所有十个事件(如果我在stream()中没有计数器变量,那么页面永远不会获得任何事件。)

我没有使用过Python或Flask,这让我非常困难,我无法看到我在做什么与网络上的其他示例不同。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

有两件事可能会干扰:

  1. 您已将debug设置为True,这会安装可能会中断流媒体的中间件(特别是Werkzeug debugger)。

    来自Flask streaming patterns documentation

      

    请注意,虽然某些WSGI中间件可能会破坏流式传输,但在配置分析器和其他可能已启用的东西的调试环境中要小心。

    但是,在使用Flask 0.10.1和Werkzeug 0.9.4的测试代码上使用curl或Chrome时,无论data: hi是什么,我都会看到debug响应正确传输标志设置。换句话说,您的代码可以与最新版本的Flask堆栈一起正常工作。

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

    在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>
    '''