Server-Sent Events (SSE)

什么是 SSE?

Server-Sent Events (SSE) 是 HTML5 标准的一部分,允许服务器主动向客户端推送数据。它基于 HTTP 协议(底层是 HTTP),使用简单的文本格式传输数据。

SSE 的工作流程?

客户端                    服务端
   |                        |
   |-- GET /events -------->|  建立连接
   |<-- 200 OK -------------|  返回事件流
   |<-- data: message1 -----|  推送消息1
   |<-- data: message2 -----|  推送消息2
   |<-- ...              ---|  持续推送

SSE 和 WebSocket 的区别?

特性 SSE WebSocket
协议 基于 HTTP 独立协议
通信方向 单向(服务器到客户端) 双向(客户端和服务器)
复杂度 简单 相对复杂
数据格式 文本(UTF-8) 二进制或文本
自动重连 内置支持 需要手动实现
防火墙穿透 优秀(基于 HTTP) 可能被阻止
适用场景 实时更新(新闻、通知、推送) 实时通信(聊天、游戏、协作)

SSE 通信的弊端?

  1. 单向通信限制。SSE 仅支持服务器向客户端推送数据,客户端无法主动发送事件,限制了交互的灵活性和实时性,尤其在模型和服务之间需要双向交互的场景中显得力不从心。
  2. 并发连接数受限。SSE 基于 HTTP 长连接,不支持复用,浏览器通常对同一源的并发连接数量有限(例如 Chrome 默认最多 6 个),在多模型、多请求并发场景下容易达到瓶颈。
  3. 不支持二进制数据。SSE 只能传输 UTF-8 编码的文本,无法直接支持二进制数据传输,不适用于图像、音频或其他非结构化数据的上下文场景,限制了协议在多模态智能体中的扩展能力。
  4. 重连和断线恢复机制不够健壮。虽然 SSE 提供了简单的自动重连机制(retry),但对连接中断、消息丢失等异常情况的处理能力较弱,无法确保消息的完整性和顺序性。

如何改进?

使用 StreamableHttp,升级版的 SSE。最大的区别就是它可以只使用普通的 HTTP 方式进行交互,按需可以使用 SSE 的方式交互。

StreamableHttp 有何优势?

  1. 高可靠性与会话恢复。支持可选 session ID 与 Last-Event-ID,可实现断线重连和断点续传,避免了 SSE 重连后上下文丢失的问题 。连接恢复后,服务器可重发客户端可能错过的消息,确保消息完整性。
  2. 资源利用更高效。无需持续保持长连接,连接仅在需要时建立,降低资源占用 。支持连接池和请求批处理机制,可进一步提高吞吐量与并发性能。
  3. 基础设施兼容性强。采用标准 HTTP,无需特殊配置 SSE 端点,在主流 CDN、负载均衡器、反向代理等标准架构中可无缝集成 。REST 风格兼容性好,易于与现有微服务、API 网关集成。
  4. 实现简单、易维护。将客户端请求和服务器响应集中到一个统一的 /message 端点,开发实践更直观 。精简了连接管理逻辑,减少开发和调试复杂度。
  5. 灵活支持各种部署与扩展。可支持 无状态服务部署,如无需会话保存的场景。同时支持 有状态部署,适用于需要会话持久化、负载均衡的复杂系统 。可按需选用 SSE 流式响应,实现实时进度通知等高级功能。