rest - 我如何告诉我的前端后台作业已使用 Web 套接字完成?

标签 rest flask websocket architecture python-rq

我的客户可以从前端启动任务(例如创建 PDF 报告),过程大致如下: architecture of old system

在此架构中,前端需要创建 ajax 调用来检查 PDF 报告是否准备就绪。

我想更新到 Web 套接字以使流程更加高效。

  1. 我应该创建另一个 Flask 项目还是添加 websocket 支持旧的吗? (添加另一个端点,例如 api.my.domain/ws/create-report)
  2. 如何向客户端发出作业已完成的事件?

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/

相关文章:

javascript - if 语句阻止套接字向客户端发送消息

jquery - Ajax 调用下载从 RESTful 服务返回的文件

java - 如何使用 Jersey 发送经过 NTLM 身份验证的发布请求?

python - 将修改后的破折号数据表保存到数据框

javascript - 在 Python Flask 中获取 JSON 列表

python - SQLAlchemy子查询,它们适用于这种情况吗

javascript - 使用 Web 套接字将 Canvas 内容从客户端传递给管理员

javascript - 为客户端应用程序提取实时服务器端数据

rest - HTTP REST 请求是访问 Azure 存储的唯一方法吗?

java - Dropwizard 使用 jakarta 而不是 javax