HTTP 的局限
HTTP 是请求—响应模型:客户端发起请求,服务器返回响应,连接结束。
如果服务器有数据要主动推给客户端(如聊天消息、实时行情),HTTP 本身做不到。
几种替代方案
轮询(Polling)
客户端定时发请求:"有新消息吗?"
缺点:
- 大量无效请求(大部分时候没有新消息);
- 实时性差(取决于轮询间隔);
- 浪费带宽和服务器资源。
长轮询(Long Polling)
客户端发请求,服务器不立即返回,而是等到有新数据时再返回;如果超时仍无数据,也返回。
客户端收到响应后立即再发一个请求。
改进:减少了无效请求,实时性接近实时。
缺点:
- 每次响应后都要重新建立连接(HTTP 开销);
- 服务器需要维持大量挂起的请求;
- 实现相对复杂。
Server-Sent Events(SSE)
基于 HTTP 的单向推送:服务器可以持续向客户端发送数据。
特点:
- 单向(只能服务器 → 客户端);
- 基于 HTTP,实现简单,自动重连;
- 文本协议(要传二进制需编码)。
适合:实时通知、日志流、进度更新等只需单向推送的场景。
WebSocket
全双工的双向通信通道。
建立过程:
- 客户端发起一个特殊的 HTTP 请求,带
Upgrade: websocket头; - 服务器同意(返回 101 Switching Protocols);
- 连接从 HTTP 协议"升级"为 WebSocket 协议;
- 之后双方可以随时互相发送数据,无需再发起请求。
优点:
- 真正的双向实时通信;
- 数据帧开销小(握手之后,每个数据帧只有 2–14 字节的头部,而 HTTP 请求的头部往往有几百字节);
- 支持二进制和文本。
代价:
- 需要服务器维护长连接状态(与无状态的 HTTP 不同,这影响架构和扩展性);
- 负载均衡需要考虑连接保持(需要"粘性会话"或专门的网关);
- 需要处理连接断开和重连;
- 某些代理和防火墙可能对 WebSocket 支持不好。
心跳与保活
长连接可能被中间设备(NAT、防火墙)在空闲时切断。
解决方案是心跳:定期发送一个小的 ping/pong 帧,保持连接活跃。
WebSocket 协议本身定义了 ping/pong 帧,应用层也可以自己实现。
重连策略
网络中断不可避免。客户端需要:
- 检测连接断开;
- 指数退避重连(避免瞬间大量重连请求压垮服务器);
- 重连后恢复状态(如重新订阅频道、拉取断连期间的消息)。
怎么选
- 只需服务器推送(通知、直播弹幕)→ SSE 更简单;
- 需要双向实时(聊天、协作编辑、多人游戏)→ WebSocket;
- 实时性要求不高(每分钟更新一次的数据看板)→ 定时轮询完全够用,也最简单。
不要为了"技术先进"而引入 WebSocket——它的复杂度和运维成本是实实在在的。
说明:本文为实时通信协议的公开知识整理。