如何在Flask中关闭Server-Send Events连接?

问题描述 投票:7回答:2

下面给出了一个使用node.js的答案。

How to close a "Server-Sent Events"-connection on the server?

但是,如何在python Flask中做同样的事情?

python flask server-sent-events
2个回答
3
投票

嗯,这取决于你的应用程序的架构。

让我举个例子(参见https://github.com/jkbr/chat/blob/master/app.py上的代码):

def event_stream():
    pubsub = red.pubsub()
    pubsub.subscribe('chat')
    for message in pubsub.listen():
        print message
        yield 'data: %s\n\n' % message['data']

@app.route('/stream')
def stream():
    return flask.Response(event_stream(),
                          mimetype="text/event-stream")

Flask稳定地向Redis(锁定操作)发出新消息,但是当Flask看到流终止时(StopIteration,如果你不是Python的新手),它会返回。

def event_stream():
    pubsub = red.pubsub()
    pubsub.subscribe('chat')
    for message in pubsub.listen():
        if i_should_close_the_connection:
            break
        yield 'data: %s\n\n' % message['data']

@app.route('/stream')
def stream():
    return flask.Response(event_stream(),
                          mimetype="text/event-stream")

0
投票

我有同样的问题,终于找到了以下解决方案here

import time
from flask import Flask, Response, stream_with_context

app = Flask(__name__)

@app.route('/stream')
def stream():
    def gen():
        try:
            i = 0
            while True:
                data = 'this is line {}'.format(i)
                print(data)
                yield data + '<br>'
                i += 1
                time.sleep(1)
        except GeneratorExit:
            print('closed')

    return Response(stream_with_context(gen()))

您可以通过订阅Redis的侦听器来启动该方法。而不是time.sleep(1)你可以等待Redis的listen()方法返回一个vlaue。您可以取消订阅Redis,而不是print('closed')。剩下的唯一问题是只有在将yield值发送给客户端时才会引发GeneratorExit异常。因此,如果Redis的listen()永远不会结束,那么你永远不会发现连接已被破坏。

© www.soinside.com 2019 - 2024. All rights reserved.