长轮询、WebSocket 与 SSE
长轮询如何模拟服务端推送?
客户端请求 → 服务端等待新消息或超时 → 返回
客户端收到返回 → 立即发起下一次请求 → 再等待
- 长轮询: 服务端延迟结束一次 HTTP 响应,等消息到达或达到超时后返回;
- 收益: 兼容常见 HTTP 环境,适合需要近实时更新但协议要求简单的场景;
- 代价: 重建请求有头部与调度开销,两个请求之间有空隙,并发挂起请求也占资源;
- 顺序风险: 多个重叠请求可能乱序或重复,需要游标和去重;
- 原文修正: 每次需要新 HTTP 请求,不代表一定建立新 TCP 连接,连接可以被复用;
WebSocket 如何维持双向通信?
客户端发起握手 → 服务端接受升级 → 建立双向通道
客户端 ⇄ 服务端持续交换消息 → 任一侧关闭或网络中断
- WebSocket: 在长期连接上提供双向消息交换,适合聊天、协同和高频互动;
- 握手: 常见 HTTP/1.1 路径通过 Upgrade 转换协议,连接建立后双方都可主动发送;
- 收益: 不必为每条消息重新发完整 HTTP 请求,交互开销较小;
- 恢复责任: 断线重连、心跳、恢复游标和消息补发需要应用设计,协议不自动恢复业务状态;
- 安全: 使用受保护连接并验证身份与 Origin,浏览器来源机制不能代替业务授权;
SSE 如何持续向浏览器发送事件?
- SSE: 客户端发起 HTTP 请求后,服务端在持续响应中发送文本事件,适合通知、进度或只读更新;
- 单向性: 该流只承担服务端到客户端发送,客户端提交命令可用独立 HTTP 请求;
- 收益: 使用常见 HTTP 基础设施,浏览器 EventSource 提供事件流接收与重连机制;
- 代价: 原生事件格式为文本,二进制需额外编码;代理缓冲和超时配置可能阻止及时交付;
- 连接限制: 并发连接数量受浏览器和 HTTP 版本影响,不能把某个旧版连接上限当普遍常数;
怎样按交互方向和频率选择?
| 需求 | 可以优先评估 | 必须补齐 |
|---|---|---|
| 兼容 HTTP 的低频近实时更新 | 长轮询 | 游标、超时与重新请求 |
| 高频双向交互 | WebSocket | 重连、鉴权、连接容量 |
| 服务端持续文本推送 | SSE | 重放边界、代理刷新与身份机制 |
- 应用语义: 通道成功建立不意味着消息持久化或已处理,业务确认仍需单独定义;
- 容量估算: 同时在线连接数、单连接内存、消息速率和重连峰值比简单请求数更有解释力;