我正在尝试使用Flask微web框架上的服务器推送功能来构建一个小型站点,但我不知道是否有框架可以直接使用。如何在Flask框架中实现服务器推送?
我用Juggernaut,但它似乎不适用于当前版本的redis-py,Juggernaut最近已被弃用。
有没有人有我的情况下的建议?
我正在尝试使用Flask微web框架上的服务器推送功能来构建一个小型站点,但我不知道是否有框架可以直接使用。如何在Flask框架中实现服务器推送?
我用Juggernaut,但它似乎不适用于当前版本的redis-py,Juggernaut最近已被弃用。
有没有人有我的情况下的建议?
看看Server-Sent Events。服务器发送的事件是一个 浏览器API,可让您保持打开一个套接字到您的服务器,订阅 更新流。欲了解更多信息,请阅读Alex MacCaw( Juggernaut的作者)发布在why he kills juggernaut上,以及为什么更简单的 服务器发送的事件在web服务器中比在 中更好。
协议非常简单。只需将mimetype text/event-stream
添加到您的 响应中即可。浏览器将保持连接打开并监听更新。从服务器发送的事件 是一行以data:
开头的文本和以下换行符。
data: this is a simple message
<blank line>
如果您想交换结构化数据,只需将您的数据转储为json并通过电线发送json即可。
一个优点是您可以在Flask中使用SSE,而不需要额外的 服务器。 github上有一个简单的chat application example,其中 使用redis作为pub/sub后端。
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('/post', methods=['POST'])
def post():
message = flask.request.form['message']
user = flask.session.get('user', 'anonymous')
now = datetime.datetime.now().replace(microsecond=0).time()
red.publish('chat', u'[%s] %s: %s' % (now.isoformat(), user, message))
@app.route('/stream')
def stream():
return flask.Response(event_stream(),
mimetype="text/event-stream")
你并不需要使用gunicron运行 示例应用程序。只要确保在运行应用程序时使用的线程,因为 否则SSE连接会挡住你的开发服务器:
if __name__ == '__main__':
app.debug = True
app.run(threaded=True)
在你只需要一个JavaScript处理功能的客户端将被调用时,一个新的 消息从服务器被推送。
var source = new EventSource('/stream');
source.onmessage = function (event) {
alert(event.data);
};
服务器发送的事件最近的火狐,Chrome和Safari浏览器是supported。 的Internet Explorer尚不支持服务器发送的事件,但预计将支持他们在 10版有两个建议Polyfills支持旧的浏览器
嗨@PeterSmith,我试过这种方法,但是,警报(event.data)永远不会出现。我运行我的Flask应用程序在端口8000和推入端口8001.所以我把“var source = new EventSource('http:// localhost:8001/push');” Flask应用程序有一个用户可以发布内容的页面。该帖子被所有其他用户广播和接收。你有什么想法? –
为什么你在不同的端口上运行? SSE的一个原因是它在你的应用程序中通过普通的http运行。你是如何运行烧瓶应用程序的?通过开发服务器?你添加了threaded = True吗?你使用的是什么浏览器? –
嗨@PeterHoffmann,我用Flask的龙卷风。是否有可能将应用程序实例和推送器实例放在龙卷风中?说不同的处理器?我还应该设置多线程吗? –
由于后续的@peter-hoffmann's answer,我已经写了一个Flask扩展来专门处理服务器发送的事件。它叫Flask-SSE,它是available on PyPI。要安装它,运行:
$ pip install flask-sse
您可以使用它像这样:
from flask import Flask
from flask_sse import sse
app = Flask(__name__)
app.config["REDIS_URL"] = "redis://localhost"
app.register_blueprint(sse, url_prefix='/stream')
@app.route('/send')
def send_message():
sse.publish({"message": "Hello!"}, type='greeting')
return "Message sent!"
并连接到从Javascript事件流,它的工作原理是这样的:
var source = new EventSource("{{ url_for('sse.stream') }}");
source.addEventListener('greeting', function(event) {
var data = JSON.parse(event.data);
// do what you want with this data
}, false);
Documentation is available on ReadTheDocs.请注意,您需要运行Redis服务器来处理发布/订阅。
[这是上个月由Flask的首席开发人员Armin Ronacher撰写的相关文章。](http://lucumr.pocoo.org/2012/8/5/stateless-and-proud/) – dumbmatter
相关:[Streaming数据与Python和烧瓶](http://stackoverflow.com/q/13386681/4279) – jfs