gpt4 book ai didi

javascript - Flask 中的服务器端事件 (SSE) 不断推送,而不是根据请求推送

转载 作者:行者123 更新时间:2023-12-03 10:00:41 27 4
gpt4 key购买 nike

我有一个 Python Flask 应用程序,当触发特定事件时(例如,通过间隔计时器、当用户按下页面上的特定按钮等),该应用程序应该将服务器端事件 (SSE) 推送到我的网页。

但是,只有当我请求应用程序这样做时,我才会让 Flask 推送消息。相反,启动应用程序后,它不断地每隔几秒向服务器推送一条消息,这不是我想要的。

我的这种行为的最小示例如下所示:

from flask import Flask
from flask import render_template, Response

from random import randint

app = Flask(__name__)

# function to push data to the server
def pushData():

# randint is just to make every message not look the same
number = randint(0,9)

print('I push data to the server: {0}'.format(number))
yield 'data: %s\n\n' % 'I am data that has been pushed to the server: {0}'.format(number)

# provide SSE stream to the web browser
@app.route('/listenForPushes')
def stream():

return Response(pushData(), mimetype="text/event-stream")

# render a simple HTML page to the browser
@app.route('/html')
def html():
return render_template('webpage.html')

# run this when the app starts. this should execute exactly one push at app start.
@app.before_first_request
def _run_on_start():
pushData()

if __name__ == "__main__":

app.run(host='0.0.0.0', debug=True, threaded=True, use_reloader=False, port=3000)

带有 SSE 事件监听器的 HTML 页面,名为 webpage.html (放入文件夹 templates 中,以便 Flask 无需任何进一步配置即可找到它)如下所示:

<html>
<head></head>
<body>This is a test page, please check the console output.

<script type="text/javascript">

var source = new EventSource('/listenForPushes');
source.onmessage = function(event) {
console.log(event.data);
}

</script>

</body>
</html>

当我现在启动应用程序时,我会不断收到每 2-3 秒推送到页面的消息,以便 Python 控制台和浏览器控制台中的输出如下所示(右键单击图像并单击“查看图像”以查看图像)放大):

console output

相反,我希望应用程序启动时只推送一次,然后不再推送。如何实现所需的行为,或者更确切地说,如何手动触发推送(例如通过调度程序、单击页面等)?

最佳答案

首先,您无法使用 SSE 从浏览器端触发请求。这是所有“服务器发送”事件之后的情况。浏览器建立连接,然后在服务器决定发送事件时等待事件到达。如果您需要能够从浏览器触发事件​​,那么您需要 WebSocket。

排除了这一点,我认为您的代码正在发生以下情况。 PushData() 在调用时仅发送一个响应。之后,它退出并且您的服务器关闭与浏览器的连接。根据 SSE 协议(protocol),浏览器在 3 秒后重新建立连接,您的函数再次运行,退出,服务器再次关闭连接。并且这个循环永远持续下去。

为了实现您想要的目标(并从一般情况下使用 SSE 中受益),pushData() 不应退出。它应该是一个生成器函数,并确定何时/是否需要向浏览器发送某些内容。这样与浏览器的连接将保持打开状态。

顺便说一句,你不需要 _run_on_start()

关于javascript - Flask 中的服务器端事件 (SSE) 不断推送,而不是根据请求推送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30615102/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com