SSE
一种基于 HTTP 的服务器向客户端单向推送数据的技术(EventSource / text/event-stream)。
[!info] related notes
SSE
一种基于 HTTP 协议的服务器向客户端单向推送数据的技术。
如果说 WebSocket 是一条“双向高速公路”,那么 SSE 就是一个“单向广播电台”。客户端打开收音机(建立连接)调到特定频道后,就只能被动接收电台(服务器)源源不断发送过来的节目内容,而不能用收音机向电台喊话。
随着 ChatGPT 等 AI 大模型的爆火,你看到的那些 AI 回复时“打字机式”逐字弹出的效果,绝大多数就是基于 SSE 技术实现的。
下面我们来详细拆解 SSE 的工作原理、特点以及它与 WebSocket 的区别。
一、 SSE 是如何工作的?
与 WebSocket 需要一套独立的复杂握手和帧结构不同,SSE 完全基于标准的 HTTP 协议,极其轻量和简单。
1. 建立连接
-
客户端向服务器发送一个普通的 HTTP GET 请求。
-
服务器接收到请求后,返回一个特定的 HTTP 响应头,告诉客户端:“我要开始流式传输数据了,请保持连接不要断开。”
其中最关键的响应头是:
Content-Type: text/event-stream(声明内容类型为事件流)Cache-Control: no-cache(禁止缓存)Connection: keep-alive(保持连接不断开)
2. 数据传输
连接建立后,服务器就可以随时向客户端发送文本数据了。SSE 的数据格式非常简单,纯文本,按行分割。每条消息由一个或多个字段组成,以两个换行符 \n\n 结束。
一个标准的数据块长这样:
id: 101
event: message
data: Hello, World!
data:核心字段,包含实际传输的数据。如果数据有多行,可以写多个data:。id:事件的唯一标识符。如果连接断开,浏览器会自动重连,并带上最后一次接收到的 ID(通过Last-Event-ID请求头),方便服务器接着推送未完成的数据。event:自定义事件类型。前端可以监听不同的事件名(默认是message)。
3. 自动重连(SSE 的超强天赋)
这是 SSE 相比 WebSocket 的一大杀手锏:浏览器原生支持断线重连。如果网络突然波动导致连接断开,浏览器底层的 EventSource API 会自动尝试重新连接服务器,不需要开发者手动写复杂的重连逻辑。
二、 SSE 与 WebSocket 的巅峰对决
很多时候,开发者会在 SSE 和 WebSocket 之间纠结。看懂下面这张表,你就知道该选谁了:
| 特性 | Server-Sent Events (SSE) | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务器 -> 客户端) | 双向(全双工) |
| 底层协议 | 标准 HTTP | 独立的 WebSocket 协议(基于 TCP) |
| 数据格式 | 仅支持文本(UTF-8) | 支持文本和二进制数据 |
| 断线重连 | 浏览器原生自动支持 | 需开发者手动实现复杂逻辑 |
| 开发难度 | 极低(简单易用) | 较高(需维护心跳、状态等) |
| 浏览器限制 | HTTP/1.1 下同一域名最多 6 个连接(HTTP/2 无此限制) | 无严格的并发连接数限制 |
三、 典型应用场景
总的来说,只要你的业务需求是“服务器单向高频向客户端发消息,而客户端很少向服务器发消息”,首选 SSE。
- AI 大模型对话流(LLM Streaming): ChatGPT、Gemini 的逐字输出效果,这是目前 SSE 最火的应用场景。客户端只需发送一次 Prompt,服务器随后将生成的 Token 持续不断地用 SSE 推送回来。
- 实时通知/消息接收: 比如社交网站的系统通知、邮件到达提醒。
- 金融/股票实时行情: 前端只需要看最新的价格走势,不需要向服务器发送大量数据。
- 日志监控平台: 实时在网页端查看服务器滚动的系统日志。
- 赛事比分直播: 实时更新体育比赛的比分和文字直播。
四、AI 对话中的暂停与中断
在 AI 流式对话场景中,用户可能需要中途停止生成。这涉及前后端的状态同步问题:
- 前端用
AbortController取消 fetch 请求,触发后端req.on('close') - 后端感知连接关闭后停止模型流,避免 token 浪费
- 消息状态需要设计状态机(
idle / streaming / cancelling / cancelled / done / error) - 流式回调中每次 append chunk 前检查消息状态,防止旧 chunk 继续写入
详见 SSE 流式输出的暂停与中断。
五、 总结一下
WebSocket 是一把牛刀,功能强大,适合大型的多人在线游戏、实时视频会议控制信令、复杂的双向即时通讯。 SSE 是一把瑞士军刀,轻巧实用,完美契合当下流行的“单向数据流”场景。它没有 WebSocket 那么重,却把单向推送这件事做到了极致。