核心是避免触发浏览器同源6连接限制:前端只建1个EventSource复用连接,后端用event字段区分消息类型;或通过3~5个无Cookie子域名分散连接,而非依赖HTTP/2多路复用。

JavaScript 中处理 SSE 在 HTTP/1.1 下的 6 连接限制,核心不是“绕开浏览器限制”,而是避免触发它——因为每个 EventSource 实例都算作一条独立 TCP 连接,而浏览器对同源域名默认只允许最多 6 条并发连接(含图片、XHR、fetch 等)。直接开多个 SSE 就会排队、卡顿甚至失败。
用一个连接承载多个业务流
最轻量、最推荐的方式:前端只创建 1 个 EventSource,后端按消息类型或会话 ID 区分数据。这样无论用户打开多少个聊天窗口、订阅多少类通知,都复用同一条连接。
- 前端传唯一标识:
new EventSource('/sse?uid=user_123') - 后端推送时加
event:字段,例如:event: chat\ndata: {"msg":"hello"}\n\n或event: notify\ndata: {"title":"更新提醒"}\n\n - 前端监听指定事件:
source.addEventListener('chat', handler),不依赖默认message
子域名散列(适合多模块强隔离场景)
当业务逻辑天然隔离(如不同产品线、不同租户),且无法统一消息格式时,可用子域名把连接分散到不同 TCP 连接池。
- 准备 3~5 个等效子域,如
sse1.example.com、sse2.example.com,全部配置泛解析 DNS 和通配符 TLS 证书 - 前端轮询分配或哈希路由:
const url = `https://sse${(i % 3) + 1}.example.com/sse` - 确保子域名不携带 Cookie(设置
Domain=sse1.example.com而非example.com),避免请求头膨胀
避免无效连接堆积
很多连接问题其实源于前端管理不当,而非协议本身。
立即学习“Java免费学习笔记(深入)”;
- 每次新建
EventSource前,主动.close()旧实例,尤其在页面切换、组件卸载时 - 不要用 setInterval 频繁重连;利用
retry字段让浏览器自动恢复:retry: 3000\n(毫秒) - 监听
onerror后做退避重试(如指数退避),而不是立刻new EventSource
别指望 HTTP/2 自动解决
即使服务启用了 HTTP/2,SSE 仍被浏览器当作 HTTP/1.1 风格长连接处理,不参与多路复用。它占用的是同源 TCP 连接槽位,和普通图片请求共享那 6 个名额。升级协议本身对 SSE 并发数没有提升作用。


















