WebSocket VS 轮询 VS SSE
Source: Dev.to
请提供您想要翻译的具体文本内容,我将把它翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。
经典的请求‑响应模型(及其局限性)
标准 Web 应用的工作方式
- 客户端(浏览器/应用)向服务器发送请求。
- 服务器 处理请求(数据库访问、计算等)。
- 服务器返回 响应。
- 连接关闭。
这个循环对大多数应用来说既简单又高效。
关键问题: 一旦响应发送完毕,服务器就无法向客户端主动推送最新数据,除非客户端再次发起请求。
示例:股票行情应用
- 客户端 A、B、C 连接并请求当前股票价格。
- 服务器响应后关闭连接。
- 随后服务器上的价格发生变化,但客户端 A、B、C 仍持有过时的数据。
服务器如何通知客户端数据已变更?
解决方案 1:WebSockets
WebSockets 在客户端和服务器之间保持 持久的全双工连接 开启。
这意味着什么?
而不是:
客户端 → 服务器 → 响应 → 连接关闭
WebSockets 保持连接打开:
客户端 ↔ 服务器 ↔ 客户端 ↔ 服务器
这允许:
- 服务器随时推送更新。
- 客户端随时发送数据。
- 双方在不关闭连接的情况下进行通信。
工作原理(简易示意图)
客户端 服务器
| — WebSocket 握手 → |
| |
| ← 接受并打开通道 — |
| |
| — 更新可以双向流动 → |
| |
一旦连接打开,任一方都可以发送数据。
WebSockets 的优点
- ✅ 实时更新
- ✅ 低延迟
- ✅ 全双工(双向通信)
WebSockets 的缺点
- ❌ 难以扩展——它是 有状态 的(服务器必须记住每个已连接的客户端)
- ❌ 在拥有数百万连接的情况下,水平扩展成本高昂
- ❌ 服务器在集群环境中必须同步彼此的更新
方案 2:轮询
轮询是 WebSockets 的最简单替代方案。
什么是轮询?
客户端反复向服务器请求新数据:
Client: “Any new updates?”
Server: “Nope.”
Client: “Any new updates?”
Server: “Yes — here you go!”
简单轮询示例
如果客户端每 2 秒 检查一次:
0 s → “Give me new data”
2 s → “Give me new data”
4 s → “Give me new data”
…
如果新数据在 3.5 秒出现,客户端将在下一个轮询时(4 秒)收到它。
最大延迟等于轮询间隔。
轮询的优点
- ✅ 易于实现
- ✅ 与负载均衡器和多台服务器兼容
- ✅ 无状态——每个请求相互独立
轮询的缺点
- ❌ 并非真正的实时
- ❌ 当没有新数据时会浪费请求
- ❌ 频繁轮询会增加网络负载
方案 3:长轮询
什么是长轮询?
服务器 保持请求打开,直到:
- 有新数据到达,或
- 超时到期
然后一次性返回数据。
示例:5 秒的长轮询
Client → Server: “Any updates?”
Server: Hold request for up to 5 seconds
If updates come within 5 s:
Server → Client: Latest updates
Client immediately re‑requests.
长轮询的优点
- ✅ 比短轮询更少的请求
- ✅ 比简单轮询更具“实时”感
- ✅ 仍然是无状态的
长轮询的缺点
- ❌ 在等待期间占用服务器资源
- ❌ 没有 WebSocket 那么即时
- ❌ 服务器必须管理保持的请求
比较方法
| 技术 | 实时性 | 可扩展性 | 服务器负载 | 复杂度 |
|---|---|---|---|---|
| Polling | 中等(有延迟) | 简单 | 中等 | 简单 |
| Long Polling | 良好 | 良好 | 中等 | 中等 |
| WebSockets | 优秀 | 困难 | 高 | 中等 |
实际考虑
是否总是需要完整的实时?
不一定。在股票图表应用中,你可能只需要最新的价格 更新,而买卖仍然可以使用常规的 POST API 路由。在这种情况下:
- WebSockets 可能大材小用。
- 轮询或长轮询完全足够。
为什么轮询在负载均衡器下工作良好
在负载均衡器后面有许多后端服务器进行扩展时:
- 轮询请求会在服务器之间分配。
- 没有单个服务器保持持久连接。
- 如果某台服务器故障,下一次轮询会被路由到另一台健康的服务器。
Final Thoughts
实时系统在于为工作选择合适的工具:
- 需要即时推送更新吗? → WebSockets
- 需要轻量级、可扩展的更新吗? → Polling / Long Polling
- 想要两者的混合? → 首先使用轮询,根据需要逐步演进
每种选择都有权衡。了解基本的通信模式有助于您做出最佳的架构决策,并避免在早期产生不必要的复杂性。