HTMLPAGE Logo

WebSocket vs SSE

作者:HTMLPAGE
发布日期:2025-11-26
待分类

对比 WebSocket 和 SSE,选择合适的实时通信方案

本文对比了 WebSocket 与 Server-Sent Events(SSE),给出选择建议并附带实现注意事项与示例代码片段,帮助在实时功能设计上做出权衡。

概述

WebSocket 是双向(full-duplex)的实时通信协议,适用于需要客户端与服务器互相推送数据的场景。SSE(通过浏览器的 EventSource)是单向(server->client)的实时推送方案,基于标准 HTTP,适合服务器向客户端持续推送事件流。

核心区别

  • 双向 vs 单向:WebSocket 支持双向通信;SSE 仅支持服务器到客户端的单向事件流。
  • 连接模型:WebSocket 通过升级 HTTP 到 ws:// 或 wss:// 建立长连接;SSE 使用普通 HTTP 长轮询/持久连接(text/event-stream)。
  • 浏览器支持与复杂度:主流浏览器均支持 SSE 与 WebSocket,但 WebSocket 更通用于复杂交互场景;SSE 实现简单,自动重连和事件ID支持。

优缺点对比(简表)

  • WebSocket:低延迟、双向、效率高,但需要处理协议帧、心跳、负载均衡粘性等。
  • SSE:实现简单、基于 HTTP、自动重连、文本事件友好,但不支持二进制帧,单连接对大规模客户端数有影响(需要连接数规模评估)。

何时选 SSE

  • 主要场景是服务器向客户端推送实时更新(通知、实时日志、状态订阅、监控面板)且无需客户端频繁发送消息。
  • 希望利用 HTTP/2 或现有 HTTP 基础设施简化部署。

何时选 WebSocket

  • 需要双向低延迟通信(协作编辑、多人实时互动、游戏、实时协商)。
  • 需要传输二进制数据或自定义消息协议时。

实践建议与注意事项

  • 负载与伸缩:长连接会占用服务器文件描述符,需配合 proxy(如 Nginx/TCP 代理)或使用专门的连接层(如 socket server、消息队列)。WebSocket 常需要 sticky session 或使用共享会话层(Redis、消息总线)。
  • 心跳/保活:两者都需要心跳/重连策略以检测死连接;SSE 有浏览器自动重连,仍建议服务器端发送心跳注入。示例心跳:发送 : keep-alive\n\n 或空事件。
  • 安全性:使用 TLS(wss:// / https)保护数据,校验来源与认证(JWT、Cookie、签名)。
  • 退化策略:在受限环境下(代理或防火墙限制 WebSocket),考虑降级为 SSE 或轮询。

简单示例(SSE 服务端 Node.js)

// express 示例 app.get('/events', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.write('retry: 3000\n\n'); const id = setInterval(() => { res.write(`data: ${JSON.stringify({ t: Date.now() })}\n\n`); }, 2000); req.on('close', () => clearInterval(id)); });

简单示例(WebSocket 服务端 Node.js + ws)

const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { ws.on('message', (msg) => console.log('recv', msg)); ws.send(JSON.stringify({ hello: 'world' })); });

结论与建议

对于以服务器推送为主的功能(如实时通知、日志、仪表盘),优先考虑 SSE:实现简单、与 HTTP 友好、可在浏览器端自动重连。对于需要双向通信或二进制传输的复杂实时交互场景,选择 WebSocket。无论选择哪种方案,都应评估连接数、心跳策略、负载均衡和安全策略。


  • 参考:WebSocket RFC、MDN 文档、常见代理(Nginx)配置建议
微信中可直接分享当前页面