期望来自服务器端的一次性响应时的长轮询与 websocket
Long-polling vs websocket when expecting one-time response from server-side
我看过很多关于实时推送通知的文章。简历是,只要您不关心 100% 的浏览器兼容性,websocket 通常是首选技术。然而,one article 表示
Long polling - potentially when you are exchanging single call with
server, and server is doing some work in background.
这正是我的情况。用户按下一个按钮,在服务器端启动一些复杂的计算,一旦答案准备就绪,服务器就会向客户端发送推送通知。问题是,我们可以说对于一次性响应的情况,长轮询是比 websockets 更好的选择吗?
或者,除非我们担心过时的浏览器支持,并且如果我要从头开始这个项目,在推送协议方面,websockets 应该总是优先于长轮询?
The question is, can we say that for the case of one-time responses,
long-polling is better choice than websockets?
不是真的。长轮询效率低下(多个传入请求,服务器必须多次检查长 运行 作业的状态),特别是如果通常的时间段足够长,您将不得不多次轮询.
如果给定的客户端页面只可能执行一次此操作,那么您真的可以选择任何一种方式。每种机制都有一些优点和缺点。
在 5-10 分钟的响应时间,您不能假设单个 http 请求会在等待响应的时间内保持活动状态,即使您确保服务器端会保持打开状态那么久。客户端或中间网络设备(代理等)不会让初始 http 连接保持打开那么久。如果你能做到这一点,那将是最有效的机制。但是,我认为对于您无法控制的随机网络配置和客户端配置,您不能指望它。
所以,这给你留下了几个我认为你已经知道的选项,但为了其他人的完整性,我将在这里描述。
选项 1:
- 建立到服务器的 websocket 连接,您可以通过它接收推送响应。
- 发出 http 请求以启动长 运行 操作。 Return 响应操作已成功启动。
- 稍后收到 websocket 推送响应。
- 关闭 webSocket(假设此页面不会再次执行此操作)。
选项 2:
- 发出 http 请求以启动长 运行 操作。 Return 操作已成功启动的响应,可能还有某种可用于将来查询的任务 ID。
- 使用 http "long polling" 到 "wait" 的答案。由于这些请求可能 "time out" 在收到响应之前,您将必须定期进行长轮询,直到收到响应。
选项 3:
- 建立webSocket连接。
- 通过 webSocket 连接发送消息以启动操作。
- 稍后收到操作完成的响应。
- 关闭 webSocket 连接(假设此页面将不再使用它)。
选项 4:
- 与选项 3 相同,但使用 socket.io 而不是普通的 webSocket 来为您提供检测信号和自动重新连接逻辑,以确保 webSocket 连接保持活动状态。
如果您纯粹从网络和服务器效率的角度来看问题,那么选项 3 或 4 可能是最有效的。您只有客户端和服务器之间的一个 TCP 连接的开销,并且该连接用于所有流量,并且该连接上的流量非常有效并且支持实际推送,因此客户端会尽快得到通知。
从体系结构的角度来看,我不喜欢选项 1,因为当您使用一种技术发起请求然后通过另一种技术发送响应时它看起来有点令人费解并且它需要您创建一个发起传入 http 请求的客户端与连接的 webSocket 之间的关联。这可以做到,但它是服务器上的额外簿记。选项 2 在架构上很简单,但效率低下(定期轮询服务器)所以它也不是我最喜欢的。
有一个替代方案不需要轮询或始终打开套接字连接。
叫做web push。
The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in, resulting in better engagement with timely new content.
一些福利是
- 您需要请求通知权限
- 您的站点需要在前台有一个 service worker 运行
- 拥有 Service Worker 还意味着您需要拥有 SSL / HTTPS
我看过很多关于实时推送通知的文章。简历是,只要您不关心 100% 的浏览器兼容性,websocket 通常是首选技术。然而,one article 表示
Long polling - potentially when you are exchanging single call with server, and server is doing some work in background.
这正是我的情况。用户按下一个按钮,在服务器端启动一些复杂的计算,一旦答案准备就绪,服务器就会向客户端发送推送通知。问题是,我们可以说对于一次性响应的情况,长轮询是比 websockets 更好的选择吗? 或者,除非我们担心过时的浏览器支持,并且如果我要从头开始这个项目,在推送协议方面,websockets 应该总是优先于长轮询?
The question is, can we say that for the case of one-time responses, long-polling is better choice than websockets?
不是真的。长轮询效率低下(多个传入请求,服务器必须多次检查长 运行 作业的状态),特别是如果通常的时间段足够长,您将不得不多次轮询.
如果给定的客户端页面只可能执行一次此操作,那么您真的可以选择任何一种方式。每种机制都有一些优点和缺点。
在 5-10 分钟的响应时间,您不能假设单个 http 请求会在等待响应的时间内保持活动状态,即使您确保服务器端会保持打开状态那么久。客户端或中间网络设备(代理等)不会让初始 http 连接保持打开那么久。如果你能做到这一点,那将是最有效的机制。但是,我认为对于您无法控制的随机网络配置和客户端配置,您不能指望它。
所以,这给你留下了几个我认为你已经知道的选项,但为了其他人的完整性,我将在这里描述。
选项 1:
- 建立到服务器的 websocket 连接,您可以通过它接收推送响应。
- 发出 http 请求以启动长 运行 操作。 Return 响应操作已成功启动。
- 稍后收到 websocket 推送响应。
- 关闭 webSocket(假设此页面不会再次执行此操作)。
选项 2:
- 发出 http 请求以启动长 运行 操作。 Return 操作已成功启动的响应,可能还有某种可用于将来查询的任务 ID。
- 使用 http "long polling" 到 "wait" 的答案。由于这些请求可能 "time out" 在收到响应之前,您将必须定期进行长轮询,直到收到响应。
选项 3:
- 建立webSocket连接。
- 通过 webSocket 连接发送消息以启动操作。
- 稍后收到操作完成的响应。
- 关闭 webSocket 连接(假设此页面将不再使用它)。
选项 4:
- 与选项 3 相同,但使用 socket.io 而不是普通的 webSocket 来为您提供检测信号和自动重新连接逻辑,以确保 webSocket 连接保持活动状态。
如果您纯粹从网络和服务器效率的角度来看问题,那么选项 3 或 4 可能是最有效的。您只有客户端和服务器之间的一个 TCP 连接的开销,并且该连接用于所有流量,并且该连接上的流量非常有效并且支持实际推送,因此客户端会尽快得到通知。
从体系结构的角度来看,我不喜欢选项 1,因为当您使用一种技术发起请求然后通过另一种技术发送响应时它看起来有点令人费解并且它需要您创建一个发起传入 http 请求的客户端与连接的 webSocket 之间的关联。这可以做到,但它是服务器上的额外簿记。选项 2 在架构上很简单,但效率低下(定期轮询服务器)所以它也不是我最喜欢的。
有一个替代方案不需要轮询或始终打开套接字连接。
叫做web push。
The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in, resulting in better engagement with timely new content.
一些福利是
- 您需要请求通知权限
- 您的站点需要在前台有一个 service worker 运行
- 拥有 Service Worker 还意味着您需要拥有 SSL / HTTPS