如何实现在瓶机架服务器推?(How to implement server push in Flas

2019-06-18 00:05发布

我想建立一个小网站与瓶微Web框架服务器推送功能,但我不知道是否有直接合作的框架。

我用剑圣 ,但它似乎是不工作的Redis-PY在当前版本中,剑圣最近已过时。

有没有人有与我的情况有何建议?

Answer 1:

看看服务器发送的事件 。 服务器发送的事件是一个浏览器的API,可以让你保持打开一个socket到你的服务器,订阅更新流。 欲了解更多信息,请阅读亚历克斯MacCaw(剑圣的作者)发布关于他为何杀死主宰 ,为什么简单的服务器发送的事件是在曼尼案件的工作比WebSockets的好工具。

该协议是很容易的。 就在MIME类型添加text/event-stream您的回复。 该浏览器将保持连接打开并监听更新。 从服务器发送的事件是文本开头的行data:和后面的换行符。

data: this is a simple message
<blank line>

如果你想交换结构化数据,只是转储数据作为JSON和通过网络发送的JSON。

一个优点是,你可以在瓶使用SSE,而无需额外的服务器。 有一个简单的聊天应用程序例如在GitHub上,它使用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运行示例应用程序。 只要确保在运行应用程序时使用的线程,否则上证所连接会挡住你的开发服务器:

if __name__ == '__main__':
    app.debug = True
    app.run(threaded=True)

在客户端,你只需要一个Javascript处理函数,当有新邮件从服务器推将被调用。

var source = new EventSource('/stream');
source.onmessage = function (event) {
     alert(event.data);
};

服务器发送的事件都支持通过最新版的Firefox,Chrome和Safari浏览器。 Internet Explorer中还不支持服务器发送的事件,但预计将支持他们在第10版有两个建议Polyfills支持旧的浏览器

  • EventSource.js
  • jquery.eventsource


Answer 2:

作为后续@彼得-霍夫曼的回答 ,我写了一个瓶扩展,专门来处理服务器发送的事件。 这就是所谓的瓶-SSE ,它是可用的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);

文件可ReadTheDocs。 请注意,您需要一个运行Redis的服务器来处理发布/订阅。



Answer 3:

Redis的是矫枉过正:使用服务器端事件

迟到了(像往常一样),但恕我直言使用Redis的可能是矫枉过正。

只要你在Python +瓶正在工作,请考虑使用如描述的发电机的功能由Panisuan乔Chasinga这个优秀的文章 。 它的主要内容是:

在客户端的index.html

var targetContainer = document.getElementById("target_div");
var eventSource = new EventSource("/stream")
  eventSource.onmessage = function(e) {
  targetContainer.innerHTML = e.data;
};
...
<div id="target_div">Watch this space...</div>

在您的服务器瓶:

def get_message():
    '''this could be any function that blocks until data is ready'''
    time.sleep(1.0)
    s = time.ctime(time.time())
    return s

@app.route('/')
def root():
    return render_template('index.html')

@app.route('/stream')
def stream():
    def eventStream():
        while True:
            # wait for source data to be available, then push it
            yield 'data: {}\n\n'.format(get_message())
    return Response(eventStream(), mimetype="text/event-stream")


文章来源: How to implement server push in Flask framework?