EventSource 默认重连机制基于 retry 响应头或浏览器默认值(约3秒),后续呈指数退避,上限几十秒;短暂抖动若未断开TCP连接则无感恢复;需监听 error 事件并结合 readyState 与时间戳判断抖动或故障。

在 JavaScript 中使用 SSE(Server-Sent Events)时,网络抖动引起的短暂停连是常见问题。浏览器原生的 EventSource 对象已内置重连机制,但默认行为可能不满足实际需求——比如重连间隔过长、无法感知中间断连、或服务端未正确响应重连请求。关键在于合理利用其自动恢复能力,并辅以主动监控与兜底策略。
理解 EventSource 的默认重连逻辑
EventSource 在连接关闭(非 200 响应、网络中断、服务端主动断开)后,会按以下规则尝试重连:
- 首次失败后,默认等待约 3 秒重试(由服务端响应头
retry:字段控制,单位毫秒;若未设置,则用浏览器默认值) - 后续每次失败,重试间隔通常呈指数退避趋势(不同浏览器实现略有差异,一般不会无限增长,上限常为几十秒)
- 只要未调用
eventSource.close(),它会持续尝试,直到成功建立新连接并收到事件
⚠️ 注意:短暂抖动(如几百毫秒断连)若发生在两个数据帧之间,且 TCP 连接未彻底断开,EventSource 可能完全无感,无需重连——这是最理想情况。
主动监听连接状态并增强可观测性
仅依赖默认行为不够直观。建议监听 error 事件,并结合时间戳判断是否为“抖动”而非永久故障:
立即学习“Java免费学习笔记(深入)”;
- 记录每次
error触发的时间和当前readyState(0=connecting, 1=open, 2=closed) - 当
readyState === 0且距离上次成功接收事件 - 避免在
error中直接new EventSource(...)——这会造成重复实例,应只在必要时调用eventSource.close()后重建
服务端配合:确保 retry 值合理 + 心跳保活
客户端表现很大程度取决于服务端输出。推荐做法:
- 设置合理的
retry: 1000(即 1 秒重试),避免默认 3 秒在高敏感场景下滞后 - 定期发送空注释行(
: ping\n\n)作为心跳,防止代理或负载均衡器因超时关闭空闲连接 - 对重连请求,服务端应快速返回 HTTP 200 + 正确的
Content-Type: text/event-stream和Cache-Control: no-cache,不要延迟或返回 5xx
兜底方案:超时检测 + 手动重建连接
当连续多次重连失败(如 3 次内均未进入 open 状态),或长时间无事件(如 30 秒),可触发主动重建:
- 用
setTimeout监控message事件间隔,超时则close()并新建EventSource - 重建前清空旧实例引用,避免内存泄漏;同时保留最后已知的游标(如
last-event-id),通过请求参数传给服务端用于断点续推 - 示例片段:
if (eventSource.readyState !== EventSource.OPEN) {<br> eventSource.close();<br> eventSource = new EventSource(`/stream?lastId=${lastId}`);<br>}


















