我的客户可以从前端启动任务(例如创建 PDF 报告),过程大致如下:
在此架构中,前端需要创建 ajax 调用来检查 PDF 报告是否准备就绪。
我想更新到 Web 套接字以使流程更加高效。
- 我应该创建另一个 Flask 项目还是添加 websocket 支持旧的吗? (添加另一个端点,例如 api.my.domain/ws/create-report)
- 如何向客户端发出作业已完成的事件?
Ps:每天,每个客户端每天会生成 1000 个任务。平均而言,每个任务只需 45 秒即可完成。
最佳答案
为了比轮询更有效,服务器可以发送“服务器发送事件”,然后客户端可以监听这些事件。服务器发送事件比 Websocket 更容易设置。 服务器发送事件与 WebSocket 一样,都比轮询更有效。通过监听服务器发送的事件,服务器在完成时只需向客户端发送一条消息,而不必响应许多“完成了吗?”来自许多客户端的轮询请求。这样,客户就可以在报告准备就绪时收到通知。
流程看起来像这样:
- 客户端通过/listen 订阅服务器的事件流
- 当flask服务器完成处理后,它会向客户端发送一条消息
- 客户端从服务器收到文件已准备就绪的消息。
客户端的代码看起来像这样来监听事件:
const evtSource = new EventSource("//api.example.com/listen", {
withCredentials: true,
});
evtSource.onmessage = (event) => {
//respond to the event here..
};
服务器将有一个端点供客户端订阅: (完整代码见下面的文章)
@app.route('/listen', methods=['GET'])
def listen():
def stream():
messages = announcer.listen() # returns a queue.Queue
while True:
msg = messages.get() # blocks until a new message arrives
yield msg
return flask.Response(stream(), mimetype='text/event-stream')
监听事件后,客户端可以开始请求以准备好 PDF 报告,流程如下所示:
- 客户提交开始生成 PDF 报告的请求。
- Flask 服务器在处理完 PDF 报告之前以 HTTP 202(已接受)响应客户端,Flask 服务器也开始等待该过程完成 (您需要弄清楚如何将客户端的信息记录在内存字典或数据库中,以便稍后可以用消息响应同一客户端)
- 当该过程完成时,它会向订阅者发送一条消息。
在此处了解有关服务器发送事件的更多信息: https://maxhalford.github.io/blog/flask-sse-no-deps/#:~:text=Server%2Dsent%20events%20(SSE),is%20all%20you%20might%20need .
在此处了解有关客户端订阅事件的更多信息: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
关于rest - 我如何告诉我的前端后台作业已使用 Web 套接字完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75750747/