SSE 如何处理断连并进行心跳保活?

考查重点:连接保活与任务状态解耦。服务端定期注释心跳并感知断开释放连接,代理禁缓冲/设合适超时;客户端退避重连而任务状态独立保留

本题目录

参考答案

核心回答

SSE 保活主要靠服务端周期性写入并刷新心跳,以及把代理的空闲超时设置得长于心跳间隔。心跳可以使用 : ping\n\n 这样的注释事件;具体间隔根据整个链路最短的空闲超时选择,不能只照抄一个固定秒数。

断连后,连接资源应释放,业务任务是否继续由任务模型决定。原生 EventSource 会自动尝试重连;基于 Fetch 的实现则要自行约定重试、退避和事件恢复。客户端重新订阅同一任务,不应重新创建一次任务。

服务端与客户端分别处理

  • 服务端:任务没有输出时仍发送心跳;感知连接关闭后停止写入,清理订阅、队列和相关协程。若任务需要后台继续,任务状态和结果独立保存,不能随连接一并销毁。
  • 代理层:关闭会延迟推送的响应缓冲,检查网关、负载均衡和服务容器的空闲与总时长限制。心跳只能缓解空闲超时,不能绕过明确的连接最大寿命。
  • 客户端:区分认证失败、限流、业务终态和瞬态网络错误;瞬态错误采用带抖动的退避并限制重试频率。收到任务终态后关闭订阅,不继续盲目重连。

如何补回断线期间的数据

服务端为可重放事件分配稳定递增序号并持久保存。重连时根据 Last-Event-ID 或显式游标补发后续事件;已过保留期则返回任务快照或明确的恢复方式。只有设置 id 而没有日志和重放逻辑,仍然无法补回丢失事件。

下面假设事件 18 已经被客户端处理,服务端仍保留后续恢复日志:

sequenceDiagram
  participant C as 客户端
  participant S as 订阅服务
  participant W as 后台任务
  participant L as 事件日志
  S-->>C: 推送任务 T 的事件 18
  Note over C,S: 连接断开,只释放订阅资源
  W->>L: 保存事件 19、20 和任务状态
  C->>S: 重连任务 T,携带游标 18
  S->>L: 读取 18 之后的已保存事件
  L-->>S: 返回事件 19、20
  S-->>C: 补发事件 19、20
  Note over C: 按事件标识去重,收到终态后关闭订阅

心跳不要推进业务恢复游标。慢客户端也需要有界缓冲和断开策略,避免一条长连接持续积压内存。网络切换、代理空闲关闭、服务重启、重复事件和主动取消,都应分别验证。

对应教程

参考资料

相关面经

2 篇

字节跳动

Agent 开发工程师
一面
查看原面经 →
SSE 如何处理断连?心跳保活怎么做?

网易

AI 应用开发工程师
查看原面经 →
SSE流式对话的底层原理,如何设计心跳保活和断线后精准续接上下文?

相关题目

4 题