WebSocket 与 SSE 全面对比
WebSocket 和 SSE (Server-Sent Events,服务器发送事件) 都是**服务端向客户端实时推送数据**的技术,用来替代低效的轮询,但设计场景、能力、使用方式完全不同。
我用**最清晰、最实用**的方式给你对比,直接覆盖开发选型核心要点。
一、核心区别一句话总结
- WebSocket:**全双工**(客户端 ↔ 服务端 双向随时通信),像**打电话**。
- SSE:**单工**(只能 服务端 → 客户端 推送),像**听广播**。
二、详细对比表(开发必看)
| 特性 | WebSocket | SSE (Server-Sent Events) |
|---|---|---|
| 通信方向 | 双向全双工 | 仅服务端 → 客户端单向 |
| 连接类型 | 独立协议(ws://、wss://) | 基于标准 HTTP/HTTPS |
| 数据格式 | 文本、二进制都支持 | 仅支持 UTF-8 文本 |
| 浏览器支持 | 所有现代浏览器 | 所有现代浏览器(IE 不支持) |
| 重连机制 | 需手动实现 | 自动重连(内置) |
| 断线消息补发 | 需手动处理 | 支持(last-event-id) |
| 跨域 | 支持,需服务端配置 | 支持,需服务端配置 |
| 适用场景 | 聊天、游戏、协同编辑、实时交互 | 通知、日志、行情、状态更新 |
| 复杂度 | 较高(协议、心跳、重连) | 极低(开箱即用) |
| 服务器资源 | 长连接,占用较高 | 长连接,占用较低 |
| 代理/防火墙 | 部分网络环境会拦截 | 完全兼容 HTTP 环境 |
三、核心技术特点详解
1. WebSocket
- 独立于 HTTP 的**新协议**
ws:///wss:// - 真正**实时双向通信**
- 可以发**文本 + 二进制**(图片、文件分片)
- 适合强交互场景:聊天、游戏、直播弹幕、多人协作
- 缺点:
- 必须单独处理**重连、心跳、断线**
- 部分防火墙/代理可能阻止 WebSocket 连接
- 服务器资源占用比 SSE 高
2. SSE
- 基于 HTTP 长连接,不需要新协议
- 只能**服务端主动推**,客户端不能发消息
- 天生自带:
- 自动重连
- 消息编号
- 断线后自动补发错过的消息
- 超轻量,前端代码只有几行
- 缺点:
- 不支持客户端向服务端发送数据
- 不支持二进制
- 大部分浏览器限制同域名最多 6 个 SSE 连接
四、前端最简代码示例
1)SSE 前端代码(超级简单)
// 建立连接
const evtSource = new EventSource("/api/sse");
// 接收消息
evtSource.onmessage = (e) => {
console.log("收到服务端消息:", e.data);
};
// 错误 & 断开(会自动重连)
evtSource.onerror = (err) => {
console.error("SSE 异常", err);
};
2)WebSocket 前端代码
// 建立连接
const ws = new WebSocket("wss://your-domain.com/ws");
// 连接成功
ws.onopen = () => {
ws.send("客户端发给服务端的消息"); // 可双向发
};
// 接收消息
ws.onmessage = (e) => {
console.log("收到:", e.data);
};
// 错误 & 断开(需手动重连)
ws.onclose = () => {
console.log("断开,需要自己重连");
};
五、最关键:你该怎么选?
✅ 用 SSE,如果:
- 只需要**服务端推消息**给前端
- 需求是:通知、公告、日志、订单状态更新、股票行情、监控数据
- 想**最快实现**、代码最少、稳定兼容
- 不想处理重连、心跳
✅ 用 WebSocket,如果:
- 需要**客户端 ↔ 服务端双向实时通信**
- 要传**二进制数据**(图片、音频、文件)
- 场景是:聊天、游戏、直播互动、协同编辑
- 不在乎多写一点重连/心跳逻辑
六、常见误区
- SSE 不能双向 = 不能用表单提交?
可以提交!用普通 AJAX/fetch 提交,SSE 只负责接收推送。 - SSE 比 WebSocket 弱?
不是弱,是**定位不同**,SSE 在单向推送场景更轻量稳定。 - SSE 只能同域?
支持跨域,服务端加响应头即可。
总结
- WebSocket = 双向实时通信(全能但复杂)
- SSE = 服务端单向推送(简单、稳定、自动重连)
- 90% 的“实时通知类需求”,SSE 足够且更好用
- 需要交互、二进制、双向通信 → 用 WebSocket