服务器发送事件未正确(刷新?)使用Flask和Redis与nginx前端

Server Sent Event isn't (flushing?) properly with Flask and Redis with nginx front

本文关键字:Flask 使用 Redis 前端 nginx 刷新 事件 服务器      更新时间:2023-09-26

我正在尝试从 PBX 服务器流式传输呼叫数据。我有一个 Golang 后端,它接收这些数据并将其发布到 Redis 中的频道。这个想法是在Web应用程序中获取实时呼叫数据。

它由两个 Flask 应用程序组成:一个是应用程序本身。它充满了 api 和 ajax 调用。第二个只是流式传输呼叫数据的路由。

由于截止日期,我不得不将应用程序一分为二,以解决线程化主应用程序和 ajax 调用的问题。

为了避免CORS问题,我设置了一个nginx前端。这是我的配置:

http {
include       mime.types;
default_type  application/octet-stream;
keepalive_timeout  65;
    server {
        listen  80;
        server_name <domain>;
        location / {
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $remote_addr;
            proxy_set_header    Host $host;
            proxy_pass  http://127.0.0.1:5000;
        }
        location /stream {
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $remote_addr;
            proxy_set_header    Host $host;
            expires off; # I set this trying to debug.
            proxy_pass  http://127.0.0.1:5001;
        }
    }
}

以下是流式处理代码:

@app.route('/stream/', methods=['GET'])
def event_socket_stream():
    def event_stream():
        stream = redis.pubsub(ignore_subscribe_messages=True)
        stream.subscribe('eventsocket')
        for message in stream.listen():
            print(message)
            yield 'data: {}'n'n'.format(message['data'])
    return Response(event_stream(), mimetype="text/event-stream")

我通过在app.run()调用中执行threaded=True来线程化上述内容。

在第一个应用程序上,我提供了一些使用 JavaScript SSE API 的 jQuery:

$(document).ready(function() {
    // Skipping above non-related functions.
    // Event Socket Stream
    var eventStream = new EventSource('/stream/');
    eventStream.onmessage = function(event) {
        console.log(event);
        fsEvent = JSON.parse(event.data);
        parseEvent(fsEvent);
    };
});

Chromium和Firefox上都会出现此问题。此事件应在我呼叫 PBX 时发送,但是,永远不会发送第一个呼叫。不过,当页面加载时,我可以看到浏览器连接到它。

GET XHR http://<domain>/stream/

当我调用 PBX 时,浏览器绝对不会收到任何消息。如果我第二次调用它,我会看到在第一次调用期间应该收到的呼叫数据。

举例说明:

调用 -> 无 -> 调用 -> 调用 1 数据 -> 调用 -> 调用 2 数据

这就是为什么我称之为"冲洗"问题。收到呼叫时,流似乎没有刷新数据。

如果我设置ignore_subscribe_messages=False,那么我在第一次调用时会收到 redis 订阅消息。

此外,如果我终止流媒体应用程序进程,浏览器会收到应该收到的最后一个事件。

任何解决方案都是100%欢迎的。

谢谢!

事实证明,

Nginx没有使其工作所需的标头。这让它工作:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

现在,一切都很好。

感谢在freenode上 #redis 的朋友!