使用 python 和烧瓶的有趣时钟流文本

fun clock streaming text with python and flask

请帮忙。使用 python 和 flask 制作一个简单的文本时钟应用程序需要什么代码来演示 flask streaming 是如何工作的?理想情况下,该应用程序会在适当的位置显示文本时间,覆盖在屏幕上,来自每秒一次的更新流。

时钟流是实时文本流的简化案例。真正的潜在需求是服务器能够同时推出像 Miguel Grinberg's Video Streaming with Flask 这样的视频和文本流(无音频),并在客户端的屏幕上显示这两个更新。 Miguel 的视频流演示有效。但是我还不知道如何让同步文本流工作。

我试过下面的代码,但有一些问题:

  1. html p 元素只是文本的占位符。它可以更改为任何可能更好用的东西。
  2. http://localhost:5000 显示 '/time_feed' 当我希望它显示 /time_feed.
  3. 的时间字符串内容时
  4. http://localhost:5000/time_feed 在 flask 服务器 运行 时什么也没有显示。当 flask 服务器突然停止时,浏览器中会出现一堆更新,例如:

    2018.11.01|20:29:272018.11.01|20:29:282018.11.01|20:29:292018.11.01|20:29:302018.11.01|20:29:312018.11.01|20 :29:322018.11.01|20:29:33

我尝试了 Streaming data with Python and Flask 但不明白如何将 javascript 或 jinga 答案应用于我的时钟代码。我是新的学习网络和烧瓶开发。

app.py:

#!python3 Flask 
# streaming clock per http://flask.pocoo.org/docs/1.0/patterns/streaming

from flask import Flask, Response, render_template, url_for
from datetime import datetime
import time

app = Flask(__name__)

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

@app.route('/time_feed')
def time_feed():
    def generate():
        while True:
            yield datetime.now().strftime("%Y.%m.%d|%H:%M:%S")
            time.sleep(1)
    return Response(generate(), mimetype='text')

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

./templates/index.html:

<title>Clock</title>
<h1>Clock</h1>
<p>{{ url_for('time_feed') }}</p>

您完全误解了它的工作原理。 streaming并不是说它可以断断续续地传输数据,而是说它可以传输大量数据,而不需要一开始就全部加载。

因此,在使用流时,您仍然只使用一个请求。这个请求是一个整体,你的浏览器只能在传输完整个数据后才能处理响应。在您的情况下,由于您使用的是无限循环,因此您的浏览器将永远等待数据。

要实现你想要的,你有两个选择:

  1. 使用js保持每秒发送请求
  2. 使用网络套接字。

更新

事实证明,某些元素可以使用特殊的 mimetype multipart/x-mixed-replace 来实现长轮询。由于我不是前端人员,也许有人可以提供或纠正我的答案。

在那个例子中你可以避免 whilesleep:

@app.route('/time_feed')
def time_feed():
    def generate():
        yield datetime.now().strftime("%Y.%m.%d|%H:%M:%S")  # return also will work
    return Response(generate(), mimetype='text') 

在模板中:

<p id="clock">Here will be date|time</p>

<script>
    var clock = document.getElementById("clock");

    setInterval(() => {
        fetch("{{ url_for('time_feed') }}")
        .then(response => {
                response.text().then(t => {clock.innerHTML = t})
            });
        }, 1000);  
</script>

在你的视频流示例中,这只是一个技巧,它不是真正的视频流的解决方案,只是因为不提供音频。如果你需要真实的视频流,你需要使用 webRTC 和 Kurento-media-server 。 对于 python,请查看 aiortc 库。