使用 Python 和 Flask 流式传输数据 [英] Streaming data with Python and Flask

查看:37
本文介绍了使用 Python 和 Flask 流式传输数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法弄清楚如何使用 Flask 的流媒体.这是我的代码:

I can't seem to figure out how to using Flask's streaming. Here's my code:

@app.route('/scans/')
def scans_query():
    url_for('static', filename='.*')
    def generate():
        yield render_template('scans.html')
        for i in xrange(50):
            sleep(.5)
            yield render_template('scans.html', **locals())
    return Response(stream_with_context(generate()))

在我的模板中:

<p>{% i %}</p>

我想在页面上看到一个每半秒改变一次的计数器.相反,我得到的最接近的是在下一行打印出每个数字的页面.

I would like to see a counter on the page that changes every half second. Instead, the closest I've gotten is the page printing out each number on the next line.

推荐答案

要替换页面上的现有内容,您可能需要 javascript,即,您可以发送它或使其向您发出请求,使用长轮询、websockets 等. 有很多方法可以做到,这里有一种使用服务器发送事件:

To replace existing content on the page you might need javascript i.e., you could send it or make it to make requests for you, use long polling, websockets, etc. There are many ways to do it, here's one that uses server send events:

#!/usr/bin/env python
import itertools
import time
from flask import Flask, Response, redirect, request, url_for

app = Flask(__name__)

@app.route('/')
def index():
    if request.headers.get('accept') == 'text/event-stream':
        def events():
            for i, c in enumerate(itertools.cycle('|/-')):
                yield "data: %s %d

" % (c, i)
                time.sleep(.1)  # an artificial delay
        return Response(events(), content_type='text/event-stream')
    return redirect(url_for('static', filename='index.html'))

if __name__ == "__main__":
    app.run(host='localhost', port=23423)

其中static/index.html:

<!doctype html>
<title>Server Send Events Demo</title>
<style>
  #data {
    text-align: center;
  }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
if (!!window.EventSource) {
  var source = new EventSource('/');
  source.onmessage = function(e) {
    $("#data").text(e.data);
  }
}
</script>
<div id="data">nothing received yet</div>

如果连接丢失,浏览器默认会在 3 秒内重新连接.如果没有更多要发送的内容,服务器可能会返回 404 或仅发送除 'text/event-stream' 以外的内容类型以响应下一个请求.即使服务器有更多数据,也可以在客户端停止,您可以调用 source.close().

The browser reconnects by default in 3 seconds if the connection is lost. if there is nothing more to send the server could return 404 or just send some other than 'text/event-stream' content type in response to the next request. To stop on the client side even if the server has more data you could call source.close().

注意:如果流不是无限的,那么使用其他技术(不是 SSE),例如,发送 javascript 片段来替换文本(无限