SSE (Server-Sent Events) 详解比 WebSocket 更轻量的实时推送方案摘要在 AI 流式输出、实时通知、数据监控等场景中我们常需要服务器主动向客户端推送数据。除了大名鼎鼎的 WebSocket还有一个被严重低估的“神器”——SSE。本文将带你彻底搞懂 SSE 的原理、协议格式、代码实战以及与 WebSocket 的选型对比。一、 什么是 SSESSEServer-Sent Events服务端推送事件是一种基于 HTTP 协议的单向实时通信技术。它是 HTML5 规范的一部分允许服务器向客户端持续发送文本数据流。用一句话概括它的本质SSE HTTP 长连接 文本事件流格式 浏览器原生自动重连 核心特点单向通信只能服务器 → 客户端客户端发请求仍走普通 HTTP基于 HTTP无需协议升级天然穿透防火墙/代理自动重连浏览器EventSourceAPI 内置断线重连机制纯文本传输数据格式为 UTF-8 文本不支持二进制轻量级无需引入第三方库浏览器原生支持二、 为什么需要 SSE痛点分析在没有 SSE 之前实现服务器推数据通常有两种方式方案缺点短轮询 (Polling)定时发请求浪费带宽和 CPU延迟高长轮询 (Long Polling)每次收到数据后连接断开再重连开销大WebSocket双向通信能力强但协议复杂、需额外部署、部分代理不友好SSE 恰好填补了中间地带当你只需要服务器持续推数据给客户端时它比轮询高效得多又比 WebSocket 简单得多。典型场景ChatGPT 等 AI 对话的流式输出、股票行情推送、构建进度条、实时日志、消息通知三、 工作原理与协议格式3.1 通信流程客户端 服务器 | | |--- GET /events --------------| | Accept: text/event-stream | | | |-- 200 OK -------------------| | Content-Type: text/event-stream | Cache-Control: no-cache | | | |-- data: {msg:hello} ----| ← 第一条数据 |-- data: {msg:world} ----| ← 第二条数据 |-- event: done --------------| ← 自定义事件 |-- data: [DONE] -------------| | ...连接保持打开... |3.2 SSE 数据格式重要SSE 是纯文本协议每条消息由以下字段组成以\n\n分隔多条消息字段必填说明data:✅消息内容多行数据每行都以data:开头event:❌事件名称默认为messageid:❌消息ID用于断线重连时告诉服务器上次收到的位置retry:❌重连等待时间毫秒示例原始响应体id: 1 event: update data: {temperature: 26.5} data: 这是一条普通消息 event: done data: [DONE]四、 代码实战4.1 前端浏览器原生 APIconstsourcenewEventSource(/api/stream);// 默认 message 事件source.onmessage(e){console.log(收到数据:,e.data);};// 自定义事件监听source.addEventListener(update,(e){console.log(更新事件:,JSON.parse(e.data));});// 错误处理 自动重连source.onerror(e){console.log(连接异常浏览器将自动重连...,e);// 如需手动关闭source.close()};4.2 后端Node.js / Express 示例app.get(/api/stream,(req,res){// ⚠️ 关键响应头res.setHeader(Content-Type,text/event-stream);res.setHeader(Cache-Control,no-cache);res.setHeader(Connection,keep-alive);letcount0;consttimersetInterval((){res.write(data:${JSON.stringify({count:count})}\n\n);if(count10){clearInterval(timer);res.write(event: done\ndata: [DONE]\n\n);res.end();}},1000);req.on(close,()clearInterval(timer));});4.3 Python FastAPI 示例AI 流式输出常用fromfastapi.responsesimportStreamingResponseimportasyncio,jsonasyncdefevent_generator():foriinrange(10):yieldfdata:{json.dumps({token:fword_{i}})}\n\nawaitasyncio.sleep(0.5)yielddata: [DONE]\n\napp.get(/chat/stream)asyncdefchat_stream():returnStreamingResponse(event_generator(),media_typetext/event-stream)五、 SSE vs WebSocket 选型指南维度SSEWebSocket通信方向单向服务器→客户端双向协议HTTPWS/WSS数据格式纯文本文本 二进制自动重连✅ 浏览器内置❌ 需手动实现实现复杂度⭐ 极低⭐⭐⭐ 较高代理/防火墙兼容✅ 优秀⚠️ 可能被拦截连接数限制同域最多 6 个HTTP/1.1无此限制适用场景AI流式输出、通知、监控聊天室、游戏、协同编辑⚠️注意HTTP/1.1 下浏览器对同一域名 SSE 连接数限制为 6 个。如果使用 HTTP/2此问题基本消除。生产环境强烈建议开启 HTTP/2。六、 常见坑与最佳实践Nginx 缓冲问题Nginx 默认会缓冲响应导致 SSE 数据延迟到达。务必添加proxy_buffering off; proxy_cache off; X-Accel-Buffering: no; # 或在后端响应头中设置跨域问题SSE 遵循 CORS 规则需正确配置Access-Control-Allow-Origin认证问题EventSourceAPI不支持自定义 Header无法传 Token。解决方案URL 参数传递 Token注意安全Cookie 认证使用fetchReadableStream手动实现 SSE 客户端推荐断点续传善用id字段 Last-Event-ID请求头实现断线后从断点继续接收不要滥用如果需要频繁双向通信请直接上 WebSocket七、 总结你的需求推荐方案服务器单向推数据快速落地✅SSEAI 大模型流式对话✅SSE业界标准实时聊天 / 多人协作 / 游戏WebSocket低频数据同步短轮询 / 长轮询SSE 不是 WebSocket 的替代品而是互补品。在合适的场景选择合适的工具才是架构设计的精髓。笔记标签#SSE#Server-Sent-Events#实时通信#WebSocket#AI流式输出#前端#后端如果这篇笔记对你有帮助欢迎点赞收藏 ❤️ ~
SSE (Server-Sent Events) 详解:比 WebSocket 更轻量的实时推送方案
发布时间:2026/6/5 20:58:11
SSE (Server-Sent Events) 详解比 WebSocket 更轻量的实时推送方案摘要在 AI 流式输出、实时通知、数据监控等场景中我们常需要服务器主动向客户端推送数据。除了大名鼎鼎的 WebSocket还有一个被严重低估的“神器”——SSE。本文将带你彻底搞懂 SSE 的原理、协议格式、代码实战以及与 WebSocket 的选型对比。一、 什么是 SSESSEServer-Sent Events服务端推送事件是一种基于 HTTP 协议的单向实时通信技术。它是 HTML5 规范的一部分允许服务器向客户端持续发送文本数据流。用一句话概括它的本质SSE HTTP 长连接 文本事件流格式 浏览器原生自动重连 核心特点单向通信只能服务器 → 客户端客户端发请求仍走普通 HTTP基于 HTTP无需协议升级天然穿透防火墙/代理自动重连浏览器EventSourceAPI 内置断线重连机制纯文本传输数据格式为 UTF-8 文本不支持二进制轻量级无需引入第三方库浏览器原生支持二、 为什么需要 SSE痛点分析在没有 SSE 之前实现服务器推数据通常有两种方式方案缺点短轮询 (Polling)定时发请求浪费带宽和 CPU延迟高长轮询 (Long Polling)每次收到数据后连接断开再重连开销大WebSocket双向通信能力强但协议复杂、需额外部署、部分代理不友好SSE 恰好填补了中间地带当你只需要服务器持续推数据给客户端时它比轮询高效得多又比 WebSocket 简单得多。典型场景ChatGPT 等 AI 对话的流式输出、股票行情推送、构建进度条、实时日志、消息通知三、 工作原理与协议格式3.1 通信流程客户端 服务器 | | |--- GET /events --------------| | Accept: text/event-stream | | | |-- 200 OK -------------------| | Content-Type: text/event-stream | Cache-Control: no-cache | | | |-- data: {msg:hello} ----| ← 第一条数据 |-- data: {msg:world} ----| ← 第二条数据 |-- event: done --------------| ← 自定义事件 |-- data: [DONE] -------------| | ...连接保持打开... |3.2 SSE 数据格式重要SSE 是纯文本协议每条消息由以下字段组成以\n\n分隔多条消息字段必填说明data:✅消息内容多行数据每行都以data:开头event:❌事件名称默认为messageid:❌消息ID用于断线重连时告诉服务器上次收到的位置retry:❌重连等待时间毫秒示例原始响应体id: 1 event: update data: {temperature: 26.5} data: 这是一条普通消息 event: done data: [DONE]四、 代码实战4.1 前端浏览器原生 APIconstsourcenewEventSource(/api/stream);// 默认 message 事件source.onmessage(e){console.log(收到数据:,e.data);};// 自定义事件监听source.addEventListener(update,(e){console.log(更新事件:,JSON.parse(e.data));});// 错误处理 自动重连source.onerror(e){console.log(连接异常浏览器将自动重连...,e);// 如需手动关闭source.close()};4.2 后端Node.js / Express 示例app.get(/api/stream,(req,res){// ⚠️ 关键响应头res.setHeader(Content-Type,text/event-stream);res.setHeader(Cache-Control,no-cache);res.setHeader(Connection,keep-alive);letcount0;consttimersetInterval((){res.write(data:${JSON.stringify({count:count})}\n\n);if(count10){clearInterval(timer);res.write(event: done\ndata: [DONE]\n\n);res.end();}},1000);req.on(close,()clearInterval(timer));});4.3 Python FastAPI 示例AI 流式输出常用fromfastapi.responsesimportStreamingResponseimportasyncio,jsonasyncdefevent_generator():foriinrange(10):yieldfdata:{json.dumps({token:fword_{i}})}\n\nawaitasyncio.sleep(0.5)yielddata: [DONE]\n\napp.get(/chat/stream)asyncdefchat_stream():returnStreamingResponse(event_generator(),media_typetext/event-stream)五、 SSE vs WebSocket 选型指南维度SSEWebSocket通信方向单向服务器→客户端双向协议HTTPWS/WSS数据格式纯文本文本 二进制自动重连✅ 浏览器内置❌ 需手动实现实现复杂度⭐ 极低⭐⭐⭐ 较高代理/防火墙兼容✅ 优秀⚠️ 可能被拦截连接数限制同域最多 6 个HTTP/1.1无此限制适用场景AI流式输出、通知、监控聊天室、游戏、协同编辑⚠️注意HTTP/1.1 下浏览器对同一域名 SSE 连接数限制为 6 个。如果使用 HTTP/2此问题基本消除。生产环境强烈建议开启 HTTP/2。六、 常见坑与最佳实践Nginx 缓冲问题Nginx 默认会缓冲响应导致 SSE 数据延迟到达。务必添加proxy_buffering off; proxy_cache off; X-Accel-Buffering: no; # 或在后端响应头中设置跨域问题SSE 遵循 CORS 规则需正确配置Access-Control-Allow-Origin认证问题EventSourceAPI不支持自定义 Header无法传 Token。解决方案URL 参数传递 Token注意安全Cookie 认证使用fetchReadableStream手动实现 SSE 客户端推荐断点续传善用id字段 Last-Event-ID请求头实现断线后从断点继续接收不要滥用如果需要频繁双向通信请直接上 WebSocket七、 总结你的需求推荐方案服务器单向推数据快速落地✅SSEAI 大模型流式对话✅SSE业界标准实时聊天 / 多人协作 / 游戏WebSocket低频数据同步短轮询 / 长轮询SSE 不是 WebSocket 的替代品而是互补品。在合适的场景选择合适的工具才是架构设计的精髓。笔记标签#SSE#Server-Sent-Events#实时通信#WebSocket#AI流式输出#前端#后端如果这篇笔记对你有帮助欢迎点赞收藏 ❤️ ~