长轮询 vs WebSockets vs 服务器发送事件(SSE)
长轮询、WebSockets 和服务器发送事件有什么区别?
长轮询、WebSockets 和服务器发送事件(SSE)是客户端(如 Web 浏览器)与 Web 服务器之间常见的通信协议。首先,我们先了解一下标准的 HTTP Web 请求流程。以下是常规 HTTP 请求的事件序列:
- 客户端打开一个连接,并向服务器请求数据。
- 服务器计算响应结果。
- 服务器通过已打开的请求将响应返回给客户端。
Ajax 轮询
轮询是一种标准技术,被大多数 AJAX 应用程序广泛使用。其基本原理是客户端不断轮询(请求)服务器获取数据。客户端发送请求并等待服务器返回数据。如果没有新数据,服务器会返回一个空响应。
- 客户端通过常规 HTTP 打开连接并向服务器请求数据。
- 请求的网页按照固定间隔(例如 0.5 秒)向服务器发送请求。
- 服务器计算响应并返回给客户端,就像普通的 HTTP 传输。
- 客户端周期性地重复上述三个步骤,以从服务器获取最新数据。
轮询的主要问题在于,客户端必须不断向服务器请求新数据,导致大量空响应,从而产生 HTTP 负载开销。
HTTP 长轮询
HTTP 长轮询是对传统轮询技术的一种改进,允许服务器在数据可用时主动向客户端推送信息。与普通轮询类似,客户端会向服务器请求数据,但它不会期望服务器立即响应。因此,这种技术有时也被称为“挂起的 GET”(Hanging GET)。
- 如果服务器暂时没有可用数据,不会立即返回空响应,而是保持请求,直到有新数据可用。
- 一旦数据可用,服务器会返回完整的响应。随后,客户端会立即重新向服务器请求数据,以确保服务器始终有一个等待中的请求,可以在新事件发生时立即推送数据。
使用 HTTP 长轮询的应用程序基本流程如下:
- 客户端使用常规 HTTP 发送初始请求,并等待响应。
- 服务器延迟响应,直到有数据更新或超时发生。
- 当有新数据时,服务器向客户端发送完整响应。
- 客户端在收到响应后,通常会立即发送新的长轮询请求,或者在短暂延迟后再次请求,以保持可接受的延迟时间。
- 每个长轮询请求都有超时时间。当连接因超时关闭时,客户端需要定期重新连接。
WebSockets
WebSocket 提供了通过单一 TCP 连接的全双工通信通道。它为客户端和服务器之间提供了一个持久连接,双方可以随时开始发送数据。客户端通过称为 WebSocket 握手的过程建立 WebSocket 连接。如果握手成功,则服务器和客户端可以随时在双向上交换数据。
WebSocket 协议使得客户端和服务器之间的通信具有更低的开销,促进了实时数据的传输。这是通过提供一种标准化的方式,使服务器能够在无需客户端请求的情况下向浏览器发送内容,同时保持连接开放,以便消息能够双向传递。通过这种方式,客户端和服务器之间可以进行双向(双向)持续对话。
服务器发送事件(SSEs)
在 SSE 中,客户端与服务器建立一个持久且长期的连接。服务器通过此连接向客户端发送数据。如果客户端需要向服务器发送数据,则需要使用其他技术或协议来实现。
- 客户端通过常规 HTTP 向服务器请求数据。
- 请求的网页与服务器建立连接。
- 服务器在有新数据时向客户端发送数据。
SSE 最适合在需要从服务器到客户端的实时流量,或者当服务器在循环中生成数据并将多个事件发送给客户端时使用。