sse是服务端单向推送的更合适选择;它基于http、轻量稳定、自动重连、兼容性强,适用于日志流、进度条、通知等场景,而websocket适用于双向交互如聊天、协同编辑。

没有“更好用”,只有“更合适”。如果你只做服务端单向推送(比如日志流、进度条、通知),SSE 几乎总是更轻、更稳、更少出错;如果要双向实时交互(比如聊天、协同编辑、交易下单),必须用 WebSocket。
什么时候该直接用 SSE?
满足以下任意一条,就别犹豫了:
- 数据流向是单向的:服务器 → 浏览器,且客户端不需要发控制指令(如“暂停”“重试”)
- 你希望开箱即用:前端一行
new EventSource("/stream"),后端加个Content-Type: text/event-stream响应头就能跑 - 你担心网关/CDN/防火墙断连:SSE 复用 HTTP 连接,不触发协议升级,Nginx、Cloudflare、阿里云SLB 默认都放行
- 你需要自动重连:浏览器原生支持,断开后默认 3 秒重试,还能通过
retry:字段自定义间隔
典型场景:/task-progress、/ai-output、/system-log —— 这些接口一旦写成 WebSocket,反而要自己实现心跳、重连、消息序列化、连接状态管理,纯属增加故障面。
为什么 WebSocket 不适合纯推送场景?
不是它不行,而是它“太能干”,干得过头了:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 握手阶段必须走
Upgrade: websocket+101 Switching Protocols,很多企业内网代理、老旧负载均衡器会静默丢弃这类请求 - 连接建立后无内置保活机制:不手动发
ping/pong,30–60 秒容易被中间设备掐断,而重连逻辑要自己写全(包括退避策略、连接池复用) - 浏览器对同一域名的
WebSocket并发数有限制(通常 6 个),但SSE是普通 HTTP 连接,可复用浏览器连接池 - 调试困难:不能直接
curl查看流内容,需用专用工具(如 wscat)或写临时客户端
一个真实踩坑点:某团队把 /notification 接口从 SSE 改成 WebSocket 后,iOS Safari 在后台标签页中连接频繁失效,因为系统会主动回收 WebSocket 连接,但对 HTTP 长连接更宽容。
SSE 的硬性限制你绕不开
这些不是“缺点”,而是设计边界,接受它才能用好它:
- 只能传文本:所有数据必须是 UTF-8 字符串,二进制内容(如图片 chunk、加密 payload)得先
Base64编码,体积膨胀约 33% - 客户端无法主动发消息:想“标记已读”或“请求重发第5条”,只能额外走一次
fetch或POST - IE 完全不支持:如果项目还要兼容 IE11,
SSE直接出局(此时长轮询比WebSocket更稳妥) - 单域名连接数有上限:Chrome 对同一域名最多 6 个并发
EventSource,超了会阻塞,需合并流或用域名分片
微信小程序是个特例:它不支持原生 EventSource,必须用 wx.request({ enableChunked: true }) 手动解析 text/event-stream 分块,这时复杂度接近 WebSocket,得重新权衡。
真正难的不是选技术,而是守住边界:推送就用 SSE,交互才上 WebSocket。一旦开始给 SSE 加“双向补丁”,或者给 WebSocket 做“单向降级”,八成已在为后续的连接抖动、重连风暴和调试黑洞埋单。










