你有没有想过,为什么 ChatGPT 能够像人类聊天一样逐字输出回答?为什么股票软件的价格能实时跳动,而无需你手动刷新?
这背后的关键技术之一,就是 SSE (Server-Sent Events),一种让服务器能够主动向浏览器推送数据的通信方式。
一、什么是 SSE?一个通俗的比喻
我们可以用一个饭店点餐的场景来理解几种不同的通信模式:
- 轮询 (Polling):你点了菜,然后每隔一分钟就跑过去问服务员:“我的菜好了没?”
- SSE:你点了菜,安心坐着。菜一做好,服务员就会主动走过来告诉你:“您的菜好了,请慢用。”
- WebSocket:你和服务员之间装了一部对讲机,你们可以随时进行双向对话。
SSE 是一种 基于 HTTP 的单向通信协议。它允许服务器在建立一次连接后,持续不断地向客户端(通常是浏览器)发送数据流。你可以把它想象成一根从服务器连接到浏览器的“数据水管”,一旦打开,服务器就能随时通过这根管子输送“水流”(数据)。
它的核心特点包括:
- ✅ 单向通信:数据流向主要是服务器 → 浏览器,类似于广播。
- ✅ 基于标准 HTTP:无需升级协议或使用特殊端口,兼容现有基础设施。
- ✅ 自动重连:连接意外中断时,浏览器会自动尝试重新建立连接。
- ✅ 轻量级:现代浏览器原生支持,无需引入额外的第三方库。
- ⏱️ 低延迟:数据近乎实时到达,延迟在毫秒级别。
二、SSE 与其他通信技术的对比
为了更清晰地定位 SSE,我们将其与常见的技术进行对比:
| 技术 |
通信方向 |
协议 |
使用复杂度 |
适用场景 |
浏览器原生支持 |
| 轮询 (HTTP Polling) |
客户端 → 服务端 |
HTTP |
简单 |
消息更新不频繁的应用 |
✅ |
| 长轮询 (HTTP Long Polling) |
客户端 → 服务端 |
HTTP |
中等 |
低频但对实时性有要求 |
✅ |
| SSE |
服务端 → 客户端 |
HTTP |
简单 |
消息流实时推送 |
✅ (除旧版IE) |
| WebSocket |
双向 |
自定义协议 |
复杂 |
聊天、游戏、IoT等强交互场景 |
✅ |
🔍 技术选型指南
- 选 SSE:当你只需要服务器向客户端单向推送数据时(如新闻推送、实时监控仪表盘),SSE 是最简单、最直接的选择。
- 选 WebSocket:当应用需要双向、全双工的实时通信时(如在线聊天室、多人在线游戏),WebSocket 是更合适的工具。
- 选轮询/长轮询:如果数据更新频率极低,且对实时性要求不高,简单的轮询反而能减少复杂度。
💡 一个精妙的比喻:
- SSE 像收音机:你只能调频接收电台的广播信号。
- WebSocket 像电话:双方可以随时进行双向对话。
- 轮询 像不断翻看信箱:你不知道是否有新信件,只能定期查看。
- 长轮询 像守在信箱旁等邮差:你一直等到有新信件投递进来才离开。
三、SSE 的工作原理
下图清晰地展示了 SSE 从建立连接到持续通信,再到断线重连的完整工作流程:

📦 关键要素解析
- HTTP 请求头:客户端在发起请求时,需要在 Header 中设置
Accept: text/event-stream,明确告知服务器:“我要接收事件流格式的数据”。
- 响应格式:服务器响应的 Header 必须包含
Content-Type: text/event-stream,并将连接保持为打开状态,以便持续发送数据。
- 事件格式:服务器推送的每条消息都有固定格式,例如
data: 这是一条消息\n\n。消息以 data: 开头,并以两个换行符 \n\n 标识一条消息的结束。
- 自动重连:连接因网络问题断开后,浏览器会根据之前收到的信息(如
Last-Event-ID)自动发起新的连接请求,实现断点续传。
四、SSE 的典型应用场景
SSE 技术因其简单高效,已在众多产品中落地应用:
1. 🤖 ChatGPT 的流式回答

你是否注意到,ChatGPT 的回答是一个词一个词“蹦”出来的?这正是利用了 SSE(或类似的流式传输技术)来实时推送 AI 生成的内容,极大地提升了对话的交互感和响应速度。
2. 🚨 后台系统实时提醒
例如:
- 新订单生成通知。
- 用户提交了新的评论或反馈。
- 后台工单状态变更。
这些需要即时感知的状态更新,都可以通过 SSE 推送给管理员界面,实现真正的实时提醒。
3. 📈 实时数据监控面板
- 股票、加密货币的价格实时变动。
- 服务器集群的 CPU、内存使用率。
- 物联网设备的传感器数据(温湿度、GPS位置)。
后端只需按固定频率(如每秒)推送一次数据,前端图表即可实现平滑的动态更新。
五、实战代码示例 (前端 + 后端)
前端代码 (原生 JavaScript)
使用浏览器原生的 EventSource API 即可轻松连接 SSE 服务。
<script>
// 创建 EventSource 对象,连接服务器端点
const eventSource = new EventSource('/sse-connect?userId=123');
// 监听通用的 message 事件
eventSource.onmessage = function(event) {
console.log('收到消息:', event.data);
// 在这里更新 DOM,将数据显示在网页上
document.getElementById('message-box').innerHTML += event.data + '<br>';
};
// 监听特定命名的事件(对应服务器发送的 event: notification)
eventSource.addEventListener('notification', function(event) {
console.log('收到通知事件:', event.data);
alert('新通知:' + event.data);
});
// 监听错误事件
eventSource.onerror = function(err) {
console.error('SSE连接出现错误', err);
// 可以在这里给用户展示连接中断的提示
};
</script>
后端代码示例 (Spring Boot)
这里以 Java 生态中常用的 Spring Boot 框架为例,展示如何创建一个 SSE 端点。
@RestController
public class SseController {
// 用于保存所有活跃连接的Emitter
private static final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();
// 浏览器连接入口
@GetMapping("/sse-connect")
public SseEmitter connect(@RequestParam String userId) {
// 创建一个SseEmitter,设置超时时间(例如30分钟)
SseEmitter emitter = new SseEmitter(30 * 60 * 1000L);
emitters.put(userId, emitter);
// 发送一条欢迎连接成功的消息
try {
emitter.send(SseEmitter.event()
.name("welcome") // 事件名称
.data("🎉 连接成功!欢迎使用 SSE 服务"));
} catch (IOException e) {
System.err.println("发送欢迎消息失败: " + e.getMessage());
}
// 设置完成和超时回调,清理资源
emitter.onCompletion(() -> emitters.remove(userId));
emitter.onTimeout(() -> emitters.remove(userId));
return emitter;
}
// 模拟一个定时推送服务,每2秒向所有客户端推送一次数据
@Scheduled(fixedRate = 2000)
public void pushData() {
emitters.forEach((userId, emitter) -> {
try {
// 模拟生成一些系统指标数据
String json = String.format(
"{\"time\": \"%s\", \"value\": %.2f}",
LocalTime.now(), Math.random() * 100
);
// 构建符合SSE格式的消息并发送
emitter.send(SseEmitter.event()
.id(UUID.randomUUID().toString()) // 事件ID,用于断线重连
.name("system-metrics") // 自定义事件类型
.data(json)); // 数据内容
} catch (IOException e) {
// 发送失败,移除此连接
emitters.remove(userId);
}
});
}
}
测试连接:
你可以使用 curl 命令来测试这个 SSE 端点:
curl --location 'localhost:18500/sse-connect?userId=1' \
--header 'Accept: text/event-stream'
实际效果:
连接建立后,你将持续收到服务器推送的 JSON 格式数据流。

六、总结
SSE 如同一位高效且专注的“信息快递员”,它基于标准的 HTTP 协议,让服务器能够主动、持续地将最新数据送达浏览器端,省去了客户端反复“询问”的开销。
尽管它不具备 WebSocket 那样的双向通信能力,但正是这种“单向专注”的特性,使其在服务器向客户端推送数据的场景下显得格外简洁和高效。如果你正在使用 Spring Boot 等框架构建需要实时数据推送的后台管理系统、监控大屏或新闻资讯站,SSE 是一个非常值得考虑的轻量级解决方案。
写在最后:在 Web 开发的工具箱里,没有一种技术是万能的。根据具体的场景需求(是单向推送还是双向交互?对实时性的要求有多高?),选择最合适而非最热门的技术,才是工程师价值的体现。

本文旨在分享 SSE 技术的核心概念与应用,希望对你有所帮助。欢迎在 云栈社区 交流更多网络通信与后端开发技术。