使用带有nginx前端的Flask和Redis,Server Sent Event不是(正在刷新?)

时间:2016-03-15 16:57:57

标签: javascript nginx flask redis server-sent-events

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

这是由两个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")

我正在threaded=True来电app.run()进行上述操作。

在第一个应用程序中,我提供了一些使用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时,浏览器几乎没有收到任何信息。如果我第二次打电话,我会看到第一次通话时应该收到的通话数据。

举例说明:

致电 - &gt;没什么 - &gt; 致电 - &gt; 呼叫1数据 - &gt; 致电 - &gt; 拨打2个数据

这就是我称之为“潮红”问题的原因。看起来,当收到呼叫时,流不会刷新数据。

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

原来Nginx没有所需的标题来使其正常工作。这让它运作起来:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

现在,一切都很顺利。

感谢freenode上#redis的朋友们!