服务端异常中断时需前端主动重连且保障数据不丢:通过 readyState 和消息 ID 准确识别崩溃,禁用默认重连并实现抖动+指数退避,依赖 Last-Event-ID 断点续传,配合 UI 反馈与功能降级。

服务端异常中断(比如进程崩溃、OOM、未捕获异常导致服务直接退出)时,SSE 连接会瞬间断开,前端不能等浏览器自动恢复,而要主动感知、可控重连、数据不丢。
监听 error 事件并准确识别真实崩溃
-
EventSource触发error事件时,需结合readyState和消息 ID 判断是否真为服务端崩溃 - 若
readyState === 0且之前已成功收到至少一条带id的消息(说明连接曾正常),基本可判定为服务端异常中断 - 主动关闭连接(调用
.close())前设isManuallyClosed = true,在error回调中跳过误判处理 - 首次连接就失败(如 DNS 错、CORS 拒绝、401/502)不属于“中断”,应显示“连接中…”而非“正在恢复”
禁用默认重连,改用抖动+指数退避
- 浏览器默认 3 秒重连,在集群重启时易引发请求风暴,必须禁用:创建时不设
retry字段 - 首次延迟设为
1000 ± 500ms(0.5–1.5 秒),打散客户端重试时间点 - 后续延迟按
2ⁿ增长(1s → 2s → 4s → 8s…),每次叠加当前值 50% 的随机偏移 - 设置最大重试次数(如 5 次)和单次上限(如 30 秒),避免无限等待
- 每次重连前检查
navigator.onLine,离线则暂停并提示“已暂停,网络恢复后自动重试”
靠 Last-Event-ID 实现断点续传
立即学习“Java免费学习笔记(深入)”;
- 只要服务端推送过带
id的事件(如id: 1623456789000),浏览器重连时会自动在请求头带上Last-Event-ID - 服务端必须严格生成单调递增的
id(推荐毫秒时间戳 + 序列号,如1717023456789-001) - 重连 URL 不用拼参数——浏览器自动处理;服务端收到
Last-Event-ID后,只返回 ID 严格大于它的消息 - 页面刷新后 ID 丢失,前端需从
localStorage读取上次保存的last_id,手动拼入 URL(如/api/events?last_id=xxx)
UI 层同步反馈与功能降级
- 连接断开瞬间显示 Toast:“⚠️ 服务暂不可用,正在尝试恢复…”(带动态省略号)
- 成功重连后自动切换为:“✅ 已恢复连接”
- 连续 3 次重连失败,升级提示:“❌ 服务异常,请稍后重试”,并显示“立即重试”按钮(点击后清空计数、新建实例)
- 立即禁用依赖实时数据的操作(如“发送”“刷新”按钮),加
disabled并附提示文案:“服务恢复后可用”
不复杂但容易忽略


















