Python 为什么我的生成器阻止Flask发送SSE响应?

Python 为什么我的生成器阻止Flask发送SSE响应?,python,flask,generator,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)

我试图使用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>

var source=新事件源(
“/事件”
);
source.onmessage=函数(事件)
{
console.log(事件);
};
stream()生成器将生成十个事件,然后返回(我特意这样做是为了演示问题,理想情况下生成器将永远运行),此时连接将断开。客户端页面在此之前没有记录任何内容,然后它会吐出所有十个事件(如果stream()中没有计数器变量,那么该页面永远不会得到任何事件)


我没有大量使用Python或Flask,这让我非常困惑,我看不出我所做的与网络上的其他示例有什么不同。非常感谢您的帮助。

有两件事可能会干扰您:

  • 您已将
    debug
    设置为
    True
    ,这将安装可能中断流的中间件(特别是)

    从:

    请注意,尽管某些WSGI中间件可能会中断流,但在使用探查器和其他您可能启用的功能的调试环境中要小心

    然而,使用Flask 0.10.1和Werkzeug 0.9.4在测试代码上使用
    curl
    或Chrome,我看到
    数据:hi
    响应正确地流式通过,无论
    调试
    标志设置如何。换句话说,您的代码在使用Flask堆栈的最新版本时工作正常

  • EventSource流受限制。如果您不是从同一主机和端口加载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>
    '''
    
    @app.route(“/”)
    def index():
    返回“”'\
    var source=新事件源(
    “/事件”
    );
    source.onmessage=函数(事件)
    {
    console.log(事件);
    };
    '''
    

  • “…您的代码在最新版本的Flask stack上正常工作。”我刚刚在我的家用机器上进行了测试,它工作得非常完美。令人尴尬的明天早上我得用我的工作机器来计算出发生了什么事。非常感谢你的帮助。