WebSocket 与 SSE 区别
针对 WebSocket 和 SSE 的面试题,你可以按照下面这个思路来组织答案,既展示基础知识的扎实,又能体现对实际场景的权衡思考。
一、先说出核心定义(一句话概括)
WebSocket 是一个全双工通信协议,允许客户端和服务器在同一个 TCP 连接上双向实时发送消息。
SSE (Server‑Sent Events) 是基于 HTTP 的单向推送技术,服务器可以持续向客户端发送文本数据,但客户端不能通过同一个连接反向发送数据。
二、对比两者关键差异(面试官最想听)
| 维度 | WebSocket | SSE |
|---|---|---|
| 通信方向 | 全双工(双方随时互发) | 单向(仅服务器→客户端) |
| 协议 | ws:// / wss://(独立于 HTTP) | 基于 HTTP(text/event-stream) |
| 数据格式 | 文本或二进制(可自由扩展) | 纯 UTF-8 文本(通常为 JSON) |
| 自动重连 | 需手动实现 | 浏览器内置自动重连 |
| 断线检测 | 需自行设计心跳(ping/pong) | 服务器可通过发送注释行保持连接 |
| 浏览器限制 | 无特殊限制 | 同一域名下最多 6 个连接(HTTP/1.1) |
| 携带 Cookie / Header | 可在握手时携带(通过Sec-WebSocket-Protocol或子协议) | 标准 EventSource 无法自定义 Header;Fetch 模拟 SSE 可以 |
| 实现复杂度(前端) | 稍复杂(处理重连、心跳、二进制) | 非常简单(几行代码监听 onmessage) |
三、分别说出各自的适用场景(展示经验)
WebSocket 适合:
- 实时聊天 / 在线客服
- 多人游戏(位置同步、动作广播)
- 协同编辑(如 Google Docs)
- 金融行情(需要客户端也能发送下单指令)
- 任何需要双向、低延迟交互的应用
SSE 适合:
- 股票价格 / 加密货币行情展示(只需推送)
- 服务器日志实时输出
- 新闻 feed / 通知中心
- 数据库变更通知(配合后端触发器)
- 只要服务器推送、客户端无需回传数据的场景
小技巧:可以说“如果客户端需要频繁向服务器发送数据,选 WebSocket;如果只是接收推送,优先用 SSE,因为它更简单、基于 HTTP,兼容性也足够好。”
四、代码层面的关键点(如果面试官让你写简单实现)
WebSocket 前端核心三步骤
const ws = new WebSocket('ws://example.com');
ws.onopen = () => ws.send('hello');
ws.onmessage = (e) => console.log(e.data);
ws.onclose = () => console.log('断开');
加分点:主动补充自动重连逻辑(利用 onclose + 定时器)和心跳(定时 send ping,服务器回应 pong)。
SSE 前端核心两步骤
const es = new EventSource('/stream');
es.onmessage = (e) => console.log(e.data);
es.onerror = () => console.log('重连中...');
加分点:说明 EventSource 会自动重连,不需要自己写重连;如果服务器发送自定义事件,用 addEventListener 监听。
五、可能的追问及应对
Q1:为什么 SSE 不能自动携带自定义 Header(如 Token)?
- 标准
EventSourceAPI 限制,无法在初始化时设置请求头。 - 解决方案:
- 把 Token 放在 URL 查询参数中(例如
/stream?token=xxx)—— 注意安全性,建议用短时效 Token。 - 使用
fetch+ReadableStream手动模拟 SSE(可以设置任意 Header)。
- 把 Token 放在 URL 查询参数中(例如
Q2:WebSocket 断线后如何恢复消息?
- 前端记录最后收到的消息 ID,重连后发送给服务器,服务器从该 ID 之后补推。
- 配合本地存储或内存队列实现“断点续传”。
Q3:WebSocket 握手是 HTTP 吗?怎么从 HTTP 升级到 WebSocket?
- 握手阶段使用 HTTP 请求,携带
Upgrade: websocket和Connection: Upgrade头部。 - 服务器返回
101 Switching Protocols,之后协议升级为 WebSocket。
Q4:如果只需要单向推送,为什么有时还用 WebSocket 而不是 SSE?
- 二进制数据:SSE 只能发文本,WebSocket 可以发
Blob/ArrayBuffer(例如推送音频、图片数据)。 - 连接数限制:SSE 在 HTTP/1.1 下有 6 个上限,WebSocket 没有。
- 更精细的控制:比如需要客户端主动取消特定订阅、或者双向 ping/pong 保持长连接。
Q5:兼容性如何?
- WebSocket:IE10+,所有现代浏览器。
- SSE:除 IE 外都支持,移动端良好;老旧项目可用
eventsource-polyfill。
六、总结一句话(给面试官留下印象)
“WebSocket 适合全双工实时交互,但实现略重;SSE 适合服务器单向推送,轻量且自带重连。实际选型时,优先考虑数据流向:需要双向就用 WebSocket,仅需接收推送就用 SSE,避免过度设计。”
七、加分行为(主动展示深度)
- 提到 WebSocket 子协议(
Sec-WebSocket-Protocol)和 扩展(如压缩)。 - 提到 HTTP/2 和 HTTP/3 对 SSE 的影响(HTTP/2 多路复用可缓解连接数限制)。
- 提到 WebTransport 作为更现代的替代方案(但面试中作为亮点提及即可)。
- 结合自己的项目经历,具体说明为什么选了其中一种,踩过什么坑(例如 WebSocket 网关兼容性、SSE 自动重连导致日志重复等)。
按照以上思路回答,你就能在面试中既清晰展示基础知识,又体现出工程实践和思考深度。建议准备一两个简短的代码片段,以及一个你实际做过的场景例子。