HTTP 长轮询与服务器发送事件(SSE)
字数 2102 2025-12-01 17:02:18

HTTP 长轮询与服务器发送事件(SSE)

  1. 传统客户端-服务器通信的局限

    • 在标准的HTTP/Web模型里,通信总是由客户端(如浏览器)主动发起请求,服务器被动响应。服务器无法在未收到请求时,主动向客户端推送新信息。
    • 对于需要实时或准实时获取服务器更新信息的应用(如聊天室、股票报价、新闻推送),传统做法是客户端轮询:每隔固定时间(如每秒)向服务器发送一次请求,询问是否有新数据。这种方式简单,但效率低下,会产生大量无效请求(即使没有数据更新),增加服务器和网络负担。
  2. HTTP 长轮询(Long Polling)

    • 概念:长轮询是对传统轮询的一种优化,旨在减少无效请求。
    • 工作原理
      1. 客户端像往常一样向服务器发起一个HTTP请求。
      2. 服务器收到请求后,并不立即响应。如果此时服务器有客户端需要的新数据,它会立即返回响应。
      3. 如果服务器没有新数据,它会保持这个连接打开,并挂起(hang)请求,直到以下任一情况发生:
        • 有新的数据产生,服务器立即使用这个已建立的连接将数据作为响应返回给客户端。
        • 一个预设的超时时间(如30秒、60秒)到达。此时即使没有新数据,服务器也会返回一个无新数据的响应(可能是一个空响应或特定状态码),然后关闭连接。
      4. 客户端收到响应(无论是包含数据的还是超时的响应)后,立即(或在短暂延迟后)发起一个新的长轮询请求,重复上述过程。
    • 效果与优缺点
      • 效果:相比短轮询,长轮询显著减少了请求次数,并且能将服务器端产生的新消息近乎实时地(取决于网络延迟)传递到客户端。
      • 优点:实现相对简单,兼容性极好(基于标准HTTP)。
      • 缺点
        • 每次请求-响应周期结束后,都需要建立新的连接,依然存在开销。
        • 服务器需要为每个挂起的连接保持资源(如内存、线程/进程),在大量并发客户端时对服务器有压力。
        • 本质上仍然是客户端“拉取”模式的一种模拟,并非真正的服务器推送。
  3. 服务器发送事件(Server-Sent Events, SSE)

    • 概念:SSE是一种真正的、单向的服务器向客户端推送数据的Web标准技术。它基于HTTP协议,提供了一种高效、低延迟的从服务器到客户端的单向通信通道。
    • 工作原理
      1. 建立连接:客户端使用JavaScript的 EventSource API,向一个特定的服务器端点发起一个普通的HTTP GET请求。该请求头中包含 Accept: text/event-stream
      2. 保持连接:服务器响应此请求时,将响应头的 Content-Type 设置为 text/event-stream,并保持此HTTP连接长期打开,不关闭。
      3. 推送数据:此后,只要服务器有需要推送的新数据,就可以通过这个持久的连接,按照SSE定义的简单文本格式(以 data: 开头的行等),随时写入(发送)一条“消息”。
      4. 接收数据:客户端的 EventSource 对象会持续监听这个连接,自动解析接收到的消息流,并触发 onmessage 等事件,将数据传递给JavaScript代码进行处理。
      5. 自动重连:如果连接意外断开,EventSource 对象会自动尝试重新连接。
    • 核心特点
      • 真正的推送:服务器可以在任意时刻主动发送数据。
      • 单向:只支持服务器到客户端方向。客户端如需向服务器发送信息,需使用另一个独立的通道(如XHR或Fetch API)。
      • 基于HTTP/HTTPS:易于在现有网络设施中部署,通常能穿透防火墙。
      • 文本协议:默认传输UTF-8文本数据。如需传输二进制数据,需先进行Base64编码。
      • 内置功能:协议规范支持事件ID、重连时间设置、自定义事件类型等。
    • 优缺点
      • 优点:真正的服务器推送,协议轻量、简单,自动重连,浏览器API易用。
      • 缺点:单向通信;浏览器端有最大并发连接数限制(同一域名下通常6个),SSE会占用一个;在不支持 EventSource 的老旧浏览器中需要降级方案(如使用长轮询)。
  4. 对比与应用场景

    • HTTP长轮询 vs SSE
      • 协议本质:长轮询是“拉取”的巧妙模拟,SSE是标准的“推送”。
      • 连接管理:长轮询频繁建立/关闭连接;SSE保持单一长连接,效率更高。
      • 消息及时性:SSE消息到达延迟通常更低。
      • 复杂度:SSE有标准API和协议格式,客户端实现更简洁;长轮询逻辑需更多手动控制。
    • 应用场景选择
      • SSE:非常适合需要服务器向客户端持续发送事件流或数据更新的场景,例如实时新闻推送、股票行情、社交媒体动态流、服务器日志监控、任务执行进度报告等。
      • HTTP长轮询:在需要极高兼容性(支持所有浏览器和HTTP/1.1环境)且对连接效率要求不是极致的场景中,仍是一个可靠的选择。它也可以作为不支持SSE环境下的降级方案。
      • 注意:对于需要全双工(双向实时通信)的场景,如在线游戏、实时协作编辑,WebSocket是更合适的技术。SSE和长轮询是实现“服务器推送”需求的两种重要技术,而WebSocket提供了一个更强大、更底层的双向通道。
HTTP 长轮询与服务器发送事件(SSE) 传统客户端-服务器通信的局限 在标准的HTTP/Web模型里,通信总是由客户端(如浏览器)主动发起请求,服务器被动响应。服务器无法在未收到请求时,主动向客户端推送新信息。 对于需要实时或准实时获取服务器更新信息的应用(如聊天室、股票报价、新闻推送),传统做法是客户端 轮询 :每隔固定时间(如每秒)向服务器发送一次请求,询问是否有新数据。这种方式简单,但效率低下,会产生大量无效请求(即使没有数据更新),增加服务器和网络负担。 HTTP 长轮询(Long Polling) 概念 :长轮询是对传统轮询的一种优化,旨在减少无效请求。 工作原理 : 客户端像往常一样向服务器发起一个HTTP请求。 服务器收到请求后, 并不立即响应 。如果此时服务器有客户端需要的新数据,它会立即返回响应。 如果服务器没有新数据,它会 保持这个连接打开,并挂起(hang)请求 ,直到以下任一情况发生: 有新的数据产生,服务器立即使用这个已建立的连接将数据作为响应返回给客户端。 一个预设的超时时间(如30秒、60秒)到达。此时即使没有新数据,服务器也会返回一个无新数据的响应(可能是一个空响应或特定状态码),然后关闭连接。 客户端收到响应(无论是包含数据的还是超时的响应)后, 立即 (或在短暂延迟后)发起一个新的长轮询请求,重复上述过程。 效果与优缺点 : 效果 :相比短轮询,长轮询显著减少了请求次数,并且能将服务器端产生的新消息近乎实时地(取决于网络延迟)传递到客户端。 优点 :实现相对简单,兼容性极好(基于标准HTTP)。 缺点 : 每次请求-响应周期结束后,都需要建立新的连接,依然存在开销。 服务器需要为每个挂起的连接保持资源(如内存、线程/进程),在大量并发客户端时对服务器有压力。 本质上仍然是客户端“拉取”模式的一种模拟,并非真正的服务器推送。 服务器发送事件(Server-Sent Events, SSE) 概念 :SSE是一种真正的、 单向 的服务器向客户端推送数据的Web标准技术。它基于HTTP协议,提供了一种高效、低延迟的从服务器到客户端的单向通信通道。 工作原理 : 建立连接 :客户端使用JavaScript的 EventSource API,向一个特定的服务器端点发起一个普通的HTTP GET请求。该请求头中包含 Accept: text/event-stream 。 保持连接 :服务器响应此请求时,将响应头的 Content-Type 设置为 text/event-stream ,并 保持此HTTP连接长期打开 ,不关闭。 推送数据 :此后,只要服务器有需要推送的新数据,就可以通过这个持久的连接,按照SSE定义的简单文本格式(以 data: 开头的行等),随时写入(发送)一条“消息”。 接收数据 :客户端的 EventSource 对象会持续监听这个连接,自动解析接收到的消息流,并触发 onmessage 等事件,将数据传递给JavaScript代码进行处理。 自动重连 :如果连接意外断开, EventSource 对象会自动尝试重新连接。 核心特点 : 真正的推送 :服务器可以在任意时刻主动发送数据。 单向 :只支持服务器到客户端方向。客户端如需向服务器发送信息,需使用另一个独立的通道(如XHR或Fetch API)。 基于HTTP/HTTPS :易于在现有网络设施中部署,通常能穿透防火墙。 文本协议 :默认传输UTF-8文本数据。如需传输二进制数据,需先进行Base64编码。 内置功能 :协议规范支持事件ID、重连时间设置、自定义事件类型等。 优缺点 : 优点 :真正的服务器推送,协议轻量、简单,自动重连,浏览器API易用。 缺点 :单向通信;浏览器端有最大并发连接数限制(同一域名下通常6个),SSE会占用一个;在不支持 EventSource 的老旧浏览器中需要降级方案(如使用长轮询)。 对比与应用场景 HTTP长轮询 vs SSE : 协议本质 :长轮询是“拉取”的巧妙模拟,SSE是标准的“推送”。 连接管理 :长轮询频繁建立/关闭连接;SSE保持单一长连接,效率更高。 消息及时性 :SSE消息到达延迟通常更低。 复杂度 :SSE有标准API和协议格式,客户端实现更简洁;长轮询逻辑需更多手动控制。 应用场景选择 : SSE :非常适合需要 服务器向客户端持续发送事件流或数据更新 的场景,例如实时新闻推送、股票行情、社交媒体动态流、服务器日志监控、任务执行进度报告等。 HTTP长轮询 :在 需要极高兼容性 (支持所有浏览器和HTTP/1.1环境)且对连接效率要求不是极致的场景中,仍是一个可靠的选择。它也可以作为不支持SSE环境下的降级方案。 注意 :对于需要 全双工 (双向实时通信)的场景,如在线游戏、实时协作编辑,WebSocket是更合适的技术。SSE和长轮询是实现“服务器推送”需求的两种重要技术,而WebSocket提供了一个更强大、更底层的双向通道。