简介:SSE(Server-Sent Events)是基于HTTP的服务器单向推送技术,凭借长连接与标准化事件流格式,成为实时通知、日志推送、大模型逐字输出等场景的主流方案。本文系统讲解SSE的定义、工作原理、消息格式、典型场景,及其与轮询、WebSocket的区别,并给出接入注意事项,帮你快速掌握这项轻量级推送技术。
SSE(Server-Sent Events,服务器推送事件)是一种基于HTTP协议的服务器推送技术。它允许服务端在一个持久的HTTP连接之上,主动、持续地向客户端发送数据流,而无需客户端反复发起请求来获取更新。
理解SSE,可以抓住三个关键点:
基于HTTP,而非独立新协议。SSE不是一套全新的协议,而是构建在标准HTTP/1.1之上的扩展用法:客户端先发起一个普通的HTTP请求,服务端返回响应头之后“不结束”这个响应,而是持续向响应体写入数据。它复用了HTTP的连接管理、鉴权、加密等既有能力,部署与理解成本都很低。
单向数据管道。可以把SSE想象成服务器向浏览器打开的一条“单向数据管道”:数据只能从服务端流向客户端。如果客户端需要向服务端发送数据,另起一个普通HTTP请求即可。
标准化的事件流格式。SSE规定了专门的媒体类型text/event-stream和统一的文本消息格式,浏览器可以原生解析,并把每条消息转换为事件回调。
一个公式可以概括其本质:SSE = HTTP扩展字段 + Keepalive长连接 + 标准化事件流格式。正因如此,目前几乎所有主流浏览器都原生支持SSE,客户端无需引入第三方库,使用内置的EventSource接口即可完成接入。
在SSE流行之前,Web应用想要“实时拿到服务端更新”,主要有几条路径,但各有明显缺陷:
SSE的价值恰好补齐了这些短板:
客户端发起一个普通GET请求,通过Accept头声明自己能接收事件流:
Accept: text/event-stream
服务端则返回如下关键响应头:
Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-alive
text/event-stream是SSE专属的媒体类型,含义是“响应体是一个持续的事件流,不要等响应结束,收到即处理”;no-cache则防止中间层缓存事件数据。
SSE消息由若干“字段行 + 空行”构成,每条消息以一个空行结束。标准字段共四个:
一个典型的事件流响应体如下(以冒号开头的行为注释行,客户端会忽略):
: keepalive commentid: 1event: messagedata: 第一条推送内容id: 2event: noticedata: {"type":"update","payload":"第二条内容"}retry: 3000
浏览器原生提供EventSource接口,示意用法如下:
// 建立连接const es = new EventSource('/api/stream');// 监听默认的message事件es.onmessage = (e) => {console.log('收到数据:', e.data);};// 监听自定义事件类型es.addEventListener('notice', (e) => {console.log('收到notice:', e.data);});// 连接异常时浏览器会自动重连,可在onerror中记录或做降级es.onerror = () => {console.log('连接异常,浏览器将自动重连');};// 不再需要推送时,主动关闭连接// es.close();
可以看到,客户端几乎不需要写重连、心跳、消息解析逻辑——这些都由浏览器统一承担,这正是SSE“轻量”的直接体现。
把SSE的完整生命周期串起来,流程大致如下:
“自动重连 + 编号续传”的组合是SSE可靠性的核心设计,也让它成为通知、日志流这类“不能丢消息”场景的常见选择。
SSE适用于“服务端主动推送、且基本不需要反向实时通信”的场景,常见包括:
反过来,如果应用要求客户端与服务端双向高频通信(如多人协同编辑、实时游戏、音视频信令),则应选择WebSocket这类全双工方案。
| 维度 | 短轮询 | 长轮询 | SSE | WebSocket |
|---|---|---|---|---|
| 通信方向 | 客户端拉 | 客户端拉 | 服务端推(单向) | 双向全双工 |
| 协议基础 | HTTP | HTTP | HTTP | 独立协议(由HTTP升级) |
| 实时性 | 差 | 较好 | 好 | 最好 |
| 断线重连 | 无 | 无 | 浏览器内建 | 需自行实现 |
| 实现复杂度 | 低 | 中 | 低 | 中高 |
| 数据格式 | 无约束 | 无约束 | 文本 | 文本与二进制 |
选型可以浓缩为一句话:只需要服务器向客户端推,选SSE;需要双向实时互通,选WebSocket。在“下行流为主、偶有上行”的场景中,业界也常用“SSE负责下行流 + 普通HTTP请求负责上行”的组合,实现简单且各取所长。
另需注意:SSE本质上是文本协议,适合传输文本与结构化文本(如JSON)。若业务以二进制数据为主,传输前需要额外编码(如Base64),此时WebSocket的二进制帧通常是更合适的选择。
回到定义本身:SSE是一种基于HTTP协议的服务器单向推送技术,通过Keepalive长连接与标准化的事件流格式,让服务端能够简单、可靠地持续向客户端发送数据。
它的核心价值在于:复用HTTP基础设施、客户端零依赖、内建自动重连与断点续传、实现与运维成本低;它的适用边界也很清晰:只支持服务端到客户端的单向推送、以文本传输为主。对实时通知、日志流、数据看板,尤其是大模型逐字输出这类“只下不上”的场景,SSE往往是比WebSocket更简单、更轻量的选择。理解了“HTTP扩展字段 + Keepalive长连接”这个本质,也就抓住了SSE技术设计的全部出发点。