一文讲清楚流式生成核心:SSE
·
摘要:本文全面介绍了 Server-Sent Events (SSE) 技术,包括其定义、核心特点、标准消息格式、前后端实现方式、与 WebSocket 的核心区别以及局限性。SSE 是基于 HTTP 的单向服务器推送方案,适用于实时通知、日志流、AI 流式输出等场景,具有浏览器原生支持、自动重连等优势,但仅支持文本传输且无法双向通信。
一、什么是 SSE
SSE 是基于标准 HTTP 协议、服务端向浏览器单向推送数据的流式通信方案,只能服务器发消息给客户端,客户端不能主动发消息给服务端。
核心特点
- 底层是普通 HTTP,不是 WebSocket:握手、传输全程复用 HTTP 1.1/2,无需额外协议升级;WebSocket 需要
Upgrade头切换协议,二者底层完全不同。 - 长连接流式传输:客户端发起一次 HTTP 请求后,服务端不关闭响应流,持续分段返回数据,连接保持打开状态。
- 单向通信:仅服务端 → 客户端推送;客户端只能在建立连接时发一次请求,后续无法上行发送数据。
- 浏览器原生 API 支持:前端内置
EventSource对象,开箱即用,不需要第三方库。 - 内置断线自动重连:网络断开后,浏览器会自动定时重试建立连接,不用自己写重连逻辑。
- 纯文本协议:传输内容是明文文本,不支持二进制数据(WebSocket 支持二进制)。
二、SSE 标准消息格式
SSE 规定响应 Content-Type 必须为 text/event-stream,每条消息由字段名: 值组成,多条消息用连续两个换行 \n\n 分隔。
常用字段
data:消息主体(最核心)
多行数据:多条data: Hello World\n\ndata:会自动拼接成一条消息,换行用\n
最终客户端收到:data: Hello data: world data: !\n\nHello\nworld\n!event:自定义事件类型
前端可以监听自定义事件,区分不同业务消息
前端:event: message-log data: 用户登录成功\n\nsource.addEventListener('message-log', callback)id:消息 ID
断线重连时,浏览器自动带上Last-Event-ID请求头,服务端可补发断线期间丢失的数据。retry:重连毫秒数
修改浏览器断线后重试等待时间,单位 ms。
三、前端使用示例(EventSource)
// 建立 SSE 连接
const source = new EventSource('/stream');
// 监听默认 message 事件(无 event 字段时触发)
source.onmessage = (e) => {
console.log('收到推送:', e.data);
};
// 监听自定义事件
source.addEventListener('notice', (e) => {
console.log('通知消息:', e.data);
});
// 连接报错/断开
source.onerror = () => {
console.log('连接异常,自动重连');
};
// 手动关闭连接
// source.close();
四、后端响应要求(关键响应头)
服务端返回必须携带这几个头,否则浏览器无法识别 SSE 流:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
然后持续输出 data: xxx\n\n 文本,不关闭响应流。
五、SSE vs WebSocket 核心区别
| 对比项 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务 → 客户端) | 双向互发 |
| 底层协议 | HTTP | 独立 ws/wss 协议(HTTP 仅握手) |
| 数据格式 | 仅纯文本 | 文本 + 二进制 |
| 浏览器原生 | EventSource 简单 API | 复杂 WebSocket 对象 |
| 自动重连 | 内置 | 需要手动实现 |
| 适用场景 | 实时通知、日志流、大盘数据、AI 流式输出 | 聊天室、实时游戏、双向交互场景 |
六、局限性
- 只能单向推送,客户端无法上传数据;需要双向通信只能选 WebSocket。
- HTTP 长连接受浏览器最大并发连接数限制(同域名最多 6 个 SSE 连接)。
- 只能传输文本,二进制数据处理麻烦。
- 老版 IE 浏览器不支持 EventSource。
更多推荐

所有评论(0)