简而言之
服务器推送事件乃单向流式协议,建于素净之HTTP。浏览器与new EventSource(url)通连,服务器持此连络,欲推data:行,则即推之。是已。无WebSocket握手,无ws://,不须升格。其能自通,历诸HTTP之代理,自2012年以来,遍于诸浏览器。
若需服务器至客户端之流,而无双向通信之需,SSE于2026年,于要义之所在,几胜WebSockets。:码简,基轻,自续,事号自生,可续。唯双向言谈之流或二进制帧,方用 WebSocket。
欲观流者乎?启免费 SSE 测试器,任填 SSE 端点,观事至如生。
三十秒心法
[ Browser ] ──── GET /events ───► [ Server ]
◄── HTTP 200, keep alive
◄── data: hello\n\n
◄── data: world\n\n
◄── data: ...
此乃持久HTTP GET,永不关闭,响应体有特定文本格式。MIME类型为text/event-stream。每两行换行即向onmessage推送事件。浏览器处理分帧、解析与重连——汝但书eventSource.onmessage = ...,事毕矣.
最简之例
服务器(Node.js — 无需库):
import http from 'node:http';
http.createServer((req, res) => {
if (req.url !== '/events') {
res.writeHead(404).end();
return;
}
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
let n = 0;
const interval = setInterval(() => {
res.write(`data: tick ${++n}\n\n`);
}, 1000);
req.on('close', () => clearInterval(interval));
}).listen(3000);
客户端(任何处 — 包括<script>标签):
const es = new EventSource('/events');
es.onmessage = (e) => console.log('got:', e.data);
es.onerror = () => console.warn('disconnected, browser will retry');
运行服务器,将客户端粘贴至浏览器控制台,二十行代码内即可实现流式传输。无构建之步骤,无库之存,无升级之商议.此乃其全篇之要.
二零二六,SSE何以见轻
每闻"实时"二字,众皆以 WebSocket 为本能,然调试代理超时、粘性会话、ALB 升级头等,费时一周。半数之用,唯服务器至客户端耳——如信息流、通知抽屉、构建日志、实时计数。此乃 Server-Sent Events 之疆域也。
Server-Sent Events 所赐,无需自建 WebSocket 者有:
一、自动重连。 途绝则瀏覽器候三秒而復連。君無需為此著筆。WebSocket之間,君終身諸案皆書此候迴循環。
2. 事項編號與續行。 若伺服器發id: 42\n,瀏覽器於次連時以Last-Event-ID: 42為首。伺服器可續行所斷。此乃此乃之妙用,使SSE于构建日志、AI流式传输及审计信息之际,尤为得心应手。藉WebSockets,此乃汝自设之协议也。
3.凡所至皆依标准HTTP。 SSE乃一GET,具Accept: text/event-stream之能。凡代理、CDN、WAF、反向代理,皆通晓之(然有一例外——详下文)。至于Cookies,Authorization,跨域资源共享、压缩——皆如常。WebSocket需升级之舞,而代理常误之。
4。无框架。唯文,行隔之。可curlSSE之端,于终端读流。试以WebSocket为之。
curl -N -H "Accept: text/event-stream" https://api.example.com/events
SSE帧之构造
其格式至简,然常使人困。每事或一或数行,以二换行(空行)
event: user-joined
id: 423
retry: 5000
data: {"userId":42,"name":"Ada"}
data: simple message
data: continuation of the same event
-
data:— 负载。复数data:同事之线得相接也\n. -
event:— 设此会名闻之es.addEventListener('user-joined', ...)若缺,则发。onmessage. -
id:— 浏览器所返者何Last-Event-ID复连之际。 -
retry:— 等待重连之毫秒数。
吾必空行忘其二者\n乃SSE之首要症结。代理与客户端之事件缓冲,皆无所见。
何时当用SSE,WebSocket,抑或长轮询?
此乃唯一抉择之树:
当用SSE者:
- 交通唯自服务器至客户端(通知、信息流、仪表盘、日志、AI令牌流)
- 欲自动重连,而无需自为书写
- 尔正流布文辞(JSON,Markdown之段,日志之行)
- 汝欲调试乎
curl
当用WebSockets时:
- 交通双向,频仍(聊、协编、多人游戏)
- 汝需二进制帧(音视频、定制协议)
- 需百毫秒内往返之应答,以通客户与服务器之讯。
当宜长轮询者:
- 汝困于基础设施,此二者皆损之(rare in 2026 but happens behind aggressive corporate proxies)。
每方均有详尽代码之剖析在焉SSE对WebSockets对长轮询深入探讨.
三生产之患
此乃每队初发SSE时所遇之弊。
1. 代理缓存,噬汝之命
Nginx,其本,蓄应。汝res.write缓冲区中落;客无所见,历数刻。二法可解,皆施之。
服务器响应首部:
X-Accel-Buffering: no
Nginx配置:
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h;
Cloudflare缓冲过多——需将SSE端点置于非缓存路径,或采用Cloudflare适配流式设置.
2. 浏览器每源6连接之限
浏览器限你于每源约6个HTTP/1.1开启之连接。若你的应用开启EventSource者,用户复启五栝,第七栝悬滞,盖无接绪之隙。有二术焉:
- 用HTTP/2或HTTP/3——接绪复用,可百流于一TCP之绪。此乃今之良术。
-
协诸栝,或依
BroadcastChannel,或循SharedWorker——一栝持EventSource,播绪于诸弟。
心跳与闲置超时
同 WebSocket 之陷阱:负载均衡器闭闲置之连。AWS ALB 之默认值为五十秒。每十五至三十秒发一注释行:
setInterval(() => res.write(':keepalive\n\n'), 15000);
以 : 开头之行为注释,依规范——此可温养连接,而弗发之。onmessage于客端.
认证与服务器发送事件
EventSource有一烦人之处:汝不可于构建时设自定义头. 无他.Authorization: Bearer ... 吾辈之选:
1. 甜饼(推荐于浏览器应用) — 浏览器自动发送之.withCredentials: true 并使CORS允许汝之原点.
const es = new EventSource('/events', { withCredentials: true });
二、查询字符串令牌—虽效,然令牌终留于服务器日志
三、fetch与ReadableStream之式—弃EventSource以就fetch,而之效如何 可受定制首部。汝失自动重连,须自解析格式,然此乃现代应用带令牌认证之正道:
const res = await fetch('/events', {
headers: { Authorization: `Bearer ${token}` },
});
const reader = res.body.getReader();
// ... parse text/event-stream chunks manually
类如 @microsoft/fetch-event-source 者为之,此乃多数现代AI流式客户端之底层所依:
SSE 乃驱动AI流式之要枢
尔若尝用ChatGPT、Claude,或近二载间任一AI对谈界面,必睹SSE之效。服务器如川流,于生成之际即递送符码:
data: {"choices":[{"delta":{"content":"Hello"}}]}
data: {"choices":[{"delta":{"content":" world"}}]}
data: [DONE]
Anthropic、OpenAI及Google之流式API,皆用SSE(或近乎一致之定制事件流格式)。通晓SSE,则可同用调试AI流式端点之工具,如调试其他网络协议然。
如何测试SSE端点
有三法,依序而用之:
1. curl -N — 无缓冲标志。速而验之根本。
curl -N -H "Accept: text/event-stream" https://api.example.com/events
二、浏览器内 SSE 测试器 — 粘贴 URL,实时观事件,察首部,察重连之态。此器免费,无需安装,即用。
三、浏览器调试工具 → 网络 → 事件流标签页 — 汝之应用既启,可睹解析之事件流,如见其生。基于Chromium之浏览器,为是设专列。
常见谬误
- "SSE已死,WebSocket代之。" WebSockets 虽盛,SSE 则寂寂无闻——然其赋能 AI 流畅传输,GitHub Actions 之日志,Vercel 部署之日志,Stripe Webhooks(虽非 SSE 本意,然理同),及诸日常所遇之"通知"功能,皆赖此也。
- "SSE 不可与 HTTP/2 相合。" 实则 SSE 与 HTTP/2 相契尤深——无六连接之限,诸流皆可并辔。 益善 之。
- "SSE纯文本,故不可发二进制。"诚然,然小二进制载荷以base64编码于JSON字段中无妨,真二进制流当用WebSocket或HTTP下载耳。
-
"SSE无ping/pong。"每十五秒发一注释行(
:heartbeat\n\n)即可。毕。
常见问题
SSE与长轮询同否?
长轮询者,客请于上,主悬以待,有数据则应,客复请之。Server-Sent Events者,一请永驻,主有数据即推。长轮询每时重开其连,SSE则否。
SSE于移行浏览器可用乎?
可也,iOS Safari、Chrome Android、Firefox Mobile皆全支之。自续连者,善应蜂窝切换。
吾可否以 React / Vue / Svelte / Solid 用 SSE?
然,如用任一订阅无异。于 EventSource 中启一 useEffect (或等值),于清理时闭之,每得消息即设状态。
服务器能承之并发 SSE 连接之极数何?
以Node.js而设,每程可容万计之连接——多系闲置,每用仅耗数KB之内存。较之每程约三二万至六五万之开启文件描述符,此乃真实之极限上限也。
当用EventSource耶?抑或用fetch与ReadableStream耶?
若cookie认证适于汝,则用EventSource(简明,自续连接,无需另费)。用fetch若汝需之Authorization請選擇標頭或自定義請求行為,並引入一庫以處理重連。
初载于悉开工具集250余种免费、注重隐私的浏览器开发者工具——SSE Tester、WebSocket Tester、JWT Decoder等,请参阅alldevtoolshub.com。












