eventsource自动重连需前后端协同:重连必须携带断点id,服务端按id精确返回后续消息;浏览器仅同源同实例异常断连时发last-event-id头,前端需存id至localstorage,刷新后通过url参数传递,服务端须支持id增量查询并兜底返回近期消息。

浏览器内置的 EventSource 会自动重连,但仅靠默认行为无法保证消息不丢、状态不错乱。关键在于:重连必须携带断点 ID,而恢复依赖服务端按 ID 精确返回后续消息——这需要前后端配合设计,不是开箱即用的功能。
自动重连不能只靠浏览器默认行为
浏览器在连接断开后会默认等待约 3 秒重试,但这个机制很“钝”:
- 超过 5 次失败后应停止自动重连,改为主动提示用户点击重试,避免无意义轮询
- 重连请求必须带上上次收到的事件 ID,否则服务端无法判断从哪继续
- 网络抖动导致的短暂断连(如切后台、Wi-Fi 切换)容易被忽略,需搭配心跳检测识别“假连上”
Last-Event-ID 不是自动生效的魔法字段
浏览器只在满足特定条件时才发送 Last-Event-ID 请求头:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 仅限同源、同 URL、同 EventSource 实例的异常断连重连;页面刷新、跳转、手动
.close()都不会触发 - 前提是服务端每条消息都带合法
id:字段(如id: 12345),且值唯一、可排序(推荐毫秒时间戳+序号) - 前端必须每次收到带 ID 的消息后,立刻存入
localStorage或内存变量,为刷新或手动重连做准备
页面刷新后要主动传 ID,不能等浏览器
刷新等于重建整个上下文,EventSource 实例和浏览器内部的 Last-Event-ID 缓存全部清空。此时必须由前端补救:
- 创建连接前,读取本地存储的最后 ID:
const lastId = localStorage.getItem('sse-last-id') || '' - 拼入 URL 参数:
new EventSource(`/api/events?last_id=${encodeURIComponent(lastId)}`) - 服务端优先解析
last_id查询参数,再 fallback 到请求头Last-Event-ID,兼顾刷新与非刷新场景
服务端必须支持基于 ID 的增量查询
客户端传了 ID,服务端若不处理,一切白搭。核心逻辑是:
- 收到请求后,提取
last_id或Last-Event-ID头 - 查数据库或缓存中 ID 大于该值的所有消息(例如 Redis ZSET 按时间排序,或 PostgreSQL 时间序列表)
- 首次连接或 ID 无效时要有兜底:返回最近 N 条或指定时间窗口内的消息,避免空白等待
- 每条响应消息必须带
id:行,确保下一次断连能继续续传
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










