【问题标题】:Long-polling vs websocket when expecting one-time response from server-side期望来自服务器端的一次性响应时,长轮询与 websocket
【发布时间】:2023-03-12 23:59:01
【问题描述】:

我已经阅读了很多关于实时推送通知的文章。并且简历是 websocket 通常是首选技术,只要您不关心 100% 浏览器兼容性。然而,one article 声明

长时间轮询 - 可能在您与 服务器,并且服务器正在后台做一些工作。

这正是我的情况。用户按下一个按钮,在服务器端启动一些复杂的计算,一旦答案准备好,服务器就会向客户端发送推送通知。问题是,我们可以说对于一次性响应的情况,长轮询比 websockets 更好吗? 或者除非我们担心过时的浏览器支持,如果我要从头开始项目,在推送协议方面,websockets 应该总是优于长轮询?

【问题讨论】:

  • 我认为你也不应该这样做。如果您进行的 API 调用触发了长时间运行的操作,则返回 202 Accepted 并带有位置以从中检索结果。参见例如farazdagi.com/blog/2014/rest-long-running-jobs
  • @jonrsharpe - 客户端仍然需要一个策略来了解长时间运行的操作何时完成以及何时可以获得结果(这是 OP 问题的重点)。你的建议没有解决这个问题。
  • @jonrsharpe - 这就是 OP 的要求。他们应该使用轮询、长轮询还是 webSocket 来获得这样的响应。您的评论(或您链接到的文章)不会以任何方式引导他们回答​​该部分问题。
  • @jonrsharpe - 您提出了第三个选项,它根本无法解决问题的推送部分。您链接到的文章是一个架构理念,缺少实现所需的一些细节。特别是,它没有说明客户端应该使用什么策略来了解长期运行的结果何时最终可以检索。而且,这正是 OP 所要求的。我评论说你的建议和那篇文章在这方面是不完整的,这是这个问题的关键部分。
  • 复杂的服务器端计算响应所需的时间范围是多少?秒?分钟?小时?如果是几秒钟,那么我只需使用 Ajax 调用并在计算完成后发送 ajax 响应。如果它足够长以至于您无法通过单个 ajax 调用来做到这一点,那么我可能会使用 webSocket,因为这可能比任何 http 轮询实现更有效。

标签: websocket long-polling


【解决方案1】:

问题是,我们可以说对于一次性响应的情况, 长轮询比 websockets 更好?

不是真的。长时间轮询效率低下(多个传入请求,您的服务器必须多次检查长时间运行作业的状态),特别是如果通常的时间段足够长以至于您将不得不进行多次轮询。


如果给定的客户端页面可能只执行一次此操作,那么您真的可以选择任何一种方式。每种机制都有一些优点和缺点。

在 5 到 10 分钟的响应时间内,您不能假设单个 http 请求会在等待响应的时间内保持活动状态,即使您确保服务器端会保持打开那么长时间。客户端或中间网络设备(代理等)只是不要让初始 http 连接保持打开那么长时间。如果你能做到这一点,那将是最有效的机制。但是,我认为您不能指望您无法控制的随机网络配置和客户端配置。

所以,这给你留下了几个我认为你已经知道的选项,但为了其他人的完整性,我将在这里描述。

选项 1:

  • 与服务器建立 websocket 连接,您可以通过该连接接收推送响应。
  • 发出 http 请求以启动长时间运行的操作。返回操作已成功启动的响应。
  • 一段时间后接收 websocket 推送响应。
  • 关闭 webSocket(假设此页面不会再这样做)。

选项 2:

  • 发出 http 请求以启动长时间运行的操作。返回操作已成功启动的响应,并且可能是某种可用于将来查询的 taskID。
  • 使用http“长轮询”来“等待”答案。由于这些请求可能会在收到响应之前“超时”,因此您必须定期进行长轮询,直到收到响应为止。

选项 3:

  • 建立 webSocket 连接。
  • 通过 webSocket 连接发送消息以启动操作。
  • 稍后会收到操作完成的响应。
  • 关闭 webSocket 连接(假设该页面不再使用它)。

选项 4:

  • 与选项 3 相同,但使用 socket.io 而不是普通的 webSocket 来为您提供心跳和自动重新连接逻辑,以确保 webSocket 连接保持活动状态。

如果您纯粹从网络和服务器效率的角度来看问题,那么选项 3 或 4 可能是最有效的。您只有客户端和服务器之间的一个 TCP 连接的开销,并且一个连接用于所有流量,并且该连接上的流量非常高效并且支持实际推送,因此客户端会尽快得到通知。

从架构的角度来看,我不喜欢选项 1,因为当您使用一种技术发起请求然后通过另一种技术发送响应时,它看起来有点令人费解,并且它需要您在两者之间建立关联发起传入 http 请求和连接的 webSocket 的客户端。可以这样做,但它是服务器上的额外簿记。选项 2 在架构上很简单,但效率低下(定期轮询服务器),所以它也不是我最喜欢的。

【讨论】:

  • 完美答案。感谢您的专业知识
【解决方案2】:

有一种替代方案不需要轮询或始终保持打开的套接字连接。

它叫web push

Push API 使 Web 应用程序能够接收从服务器推送给它们的消息,无论 Web 应用程序是否在前台,甚至当前是否已加载到用户代理上。这让开发者可以向选择加入的用户提供异步通知和更新,从而更好地及时参与新内容。

一些福利是

  • 您需要请求通知权限
  • 您的站点需要有一个在前台运行的服务人员
  • 拥有 Service Worker 也意味着您需要拥有 SSL / HTTPS

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    相关资源
    最近更新 更多