sse通过last-event-id实现断线续传需客户端和服务端协作:客户端自动发送最后一次接收的id,服务端据此返回后续消息;id须唯一、单调递增且由服务端生成。

SSE(Server-Sent Events)本身不提供内置的消息确认或重传机制,但可通过 Last-Event-ID 配合服务端状态管理,实现断线后从上次接收位置继续接收消息。关键在于客户端自动携带 ID、服务端识别并返回对应历史消息——它不是“自动恢复”,而是需双方协作设计。
客户端如何发送 Last-Event-ID
浏览器在 SSE 连接断开重连时,会自动将最后一次收到的 id: 字段值作为请求头 Last-Event-ID 发送给服务端(前提是消息中包含合法的 id)。你无需手动设置该请求头。
- 确保每条 SSE 消息都带
id:行,且值唯一、单调递增(如时间戳或自增序号) - 避免
id:为空或含非法字符(如换行、空格),否则浏览器可能忽略或清空该值 - 连接初始化时若未设置
lastEventId,浏览器不会发送Last-Event-ID请求头
服务端如何解析并响应 Last-Event-ID
服务端需主动读取请求头 Last-Event-ID,查找该 ID 之后的消息,并按顺序推送。这不是标准行为,必须由后端逻辑实现。
- Node.js(Express)示例:用
req.headers['last-event-id']获取 ID,查数据库/缓存中大于该 ID 的消息 - 消息存储建议使用有序结构(如 Redis ZSET、PostgreSQL 时间序列表),支持按 ID 或时间范围快速查询
- 首次连接时该头为空,应返回全部最新消息或从某个起点开始(如最近 10 条)
消息 ID 的设计要点
ID 是恢复的关键锚点,必须满足可排序、可追溯、无歧义。
- 推荐用毫秒级时间戳 + 微秒/序列号组合(如
1717023456789-001),避免纯时间戳并发冲突 - 不要用 UUID 或随机字符串——无法自然排序,服务端难判断“之后”的消息
- 服务端生成 ID 并写入消息,客户端绝不自行构造或修改
id:
注意连接重建的边界情况
浏览器只在同源、同 URL、同事件类型下才复用 Last-Event-ID。以下情况会导致 ID 丢失:
- 页面刷新或跳转后重新
new EventSource(url),若 URL 带不同参数(如加了时间戳),ID 不会传递 - 服务端返回非 200 响应(如 503),浏览器可能丢弃当前 ID 并重试时不带该头
- 网络超时(
timeout触发)后重连,只要 URL 不变且服务端响应 200,ID 通常保留
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











