什么是SSE
SSE(Server-Sent Events),轻量级单向实时通信技术,专为 "服务器向客户端持续推送流式数据" 而设计。
SSE本质是客户端发送一个普通的HTTP请求,服务器保持连接打开,然后持续不断地向客户端推送数据。
- 普通http:一次请求 -> 一次响应 -> 连接关闭
- SSE:一次请求 -> 多次响应 -> 连接长期保持
SSE的特点
- 单向通信:只支持服务器->客户端推送,不支持客户端通过SSE向服务器发送数据
- 自动重连:浏览器原生支持,无需手动实现
- 断点续传:通过
Last-Event-ID头,断线重连后可以从上次断开的位置继续接收数据 - http原生支持
- 多个SSE可以共享一个TCP连接,降低服务器开销
基于以上特点,SSE是目前AI聊天、日志监控等场景的首选方案。
工作步骤
步骤:
- 连接建立
- 服务器响应
- 数据推送
- 连接关闭
连接建立
客户端通过EventSource对象向服务器发送一个http GET请求,请求头中有Accept: text/event-stream。
vbnet
GET /api/chat HTTP/1.1
Host: example.com
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
服务器响应
yaml
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Transfer-Encoding: chunked
数据推送
数据必须遵循SSE标准格式
yaml
id: 123
event: message
data: 这是第一条消息
data:这是第二条消息
这还是第二条消息
retry: 5000
id: 消息id,可选,用于断点续传 event:自定义事件类型,默认是message data: 消息内容,可以跨多行 retry: 断线重连间隔多少ms
豆包网页版的SSE截图:

代码实现
前端示例
ts
window.mockChat = () => {
// 创建SSE连接
const eventSource = new EventSource('http://localhost:3000/api/chat?prompt=你好')
// 监听默认message事件
eventSource.onmessage = (e) => {
console.log('收到消息:', e.data)
}
// 监听自定义事件
eventSource.addEventListener('complete', (e) => {
console.log('回答生成完成')
eventSource.close() // 关闭连接
})
// 监听错误事件
eventSource.onerror = (e) => {
// @todo
}
}
服务端示例
js
import express from 'express'
const app = express()
app.get('/api/chat', (req, res) => {
// 设置SSE响应头
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*',
})
// 模拟大模型流式生成回答
const answer = '你好,我是AI助手,很高兴为你服务!'
let index = 0
const timer = setInterval(() => {
if (index < answer.length) {
// 每次发送一个字
res.write(`data: ${answer[index]}\n\n`)
index++
} else {
// 发送完成事件
res.write('event: complete\n')
res.write('data: done\n\n')
clearInterval(timer)
res.end()
}
}, 100)
// 客户端关闭连接时清理资源
req.on('close', () => {
clearInterval(timer)
console.log('客户端断开连接')
})
})
app.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000')
})
效果截图


SSE和WebSocket的对比
| 对比维度 | SSE (Server-Sent Events) | WebSocket |
|---|---|---|
| 协议基础 | 纯 HTTP/HTTPS 协议 GET 请求 | 独立的 WebSocket 协议 |
| 通信方向 | 单向:仅服务器→客户端推送 | 全双工:客户端↔服务器双向自由发送 |
| 数据格式 | 仅支持文本数据(UTF-8),内置事件流格式 | 支持二进制和文本数据,无内置格式,完全自定义 |
| 自动重连 | 浏览器原生支持,断线后自动重连 | 无原生支持,需要手动实现重连、心跳、退避算法 |
| 兼容性 | 所有现代浏览器支持,IE10+ | 所有现代浏览器支持,IE10+ |
| CDN / 代理支持 | 完美支持,可利用 CDN 缓存、边缘计算 | 较差,多数 CDN 不支持 WebSocket 代理 |
| 性能开销 | 极低,HTTP/2 支持多路复用,多个 SSE 连接共享一个 TCP 连接 | 中等,每个 WebSocket 连接独占一个 TCP 连接 |
最后
SSE 是一种轻量级、简单、可靠的实时通信技术,它没有 WebSocket 那么强大,但在 "大模型一次请求,流式响应" 这个业务场景下,它是简单、成本低、兼容性最好的选择。