我正在嘗試使用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