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 通信的弊端?
- 单向通信限制。SSE 仅支持服务器向客户端推送数据,客户端无法主动发送事件,限制了交互的灵活性和实时性,尤其在模型和服务之间需要双向交互的场景中显得力不从心。
- 并发连接数受限。SSE 基于 HTTP 长连接,不支持复用,浏览器通常对同一源的并发连接数量有限(例如 Chrome 默认最多 6 个),在多模型、多请求并发场景下容易达到瓶颈。
- 不支持二进制数据。SSE 只能传输 UTF-8 编码的文本,无法直接支持二进制数据传输,不适用于图像、音频或其他非结构化数据的上下文场景,限制了协议在多模态智能体中的扩展能力。
- 重连和断线恢复机制不够健壮。虽然 SSE 提供了简单的自动重连机制(retry),但对连接中断、消息丢失等异常情况的处理能力较弱,无法确保消息的完整性和顺序性。
如何改进?
使用 StreamableHttp,升级版的 SSE。最大的区别就是它可以只使用普通的 HTTP 方式进行交互,按需可以使用 SSE 的方式交互。
StreamableHttp 有何优势?
- 高可靠性与会话恢复。支持可选 session ID 与 Last-Event-ID,可实现断线重连和断点续传,避免了 SSE 重连后上下文丢失的问题 。连接恢复后,服务器可重发客户端可能错过的消息,确保消息完整性。
- 资源利用更高效。无需持续保持长连接,连接仅在需要时建立,降低资源占用 。支持连接池和请求批处理机制,可进一步提高吞吐量与并发性能。
- 基础设施兼容性强。采用标准 HTTP,无需特殊配置 SSE 端点,在主流 CDN、负载均衡器、反向代理等标准架构中可无缝集成 。REST 风格兼容性好,易于与现有微服务、API 网关集成。
- 实现简单、易维护。将客户端请求和服务器响应集中到一个统一的 /message 端点,开发实践更直观 。精简了连接管理逻辑,减少开发和调试复杂度。
- 灵活支持各种部署与扩展。可支持 无状态服务部署,如无需会话保存的场景。同时支持 有状态部署,适用于需要会话持久化、负载均衡的复杂系统 。可按需选用 SSE 流式响应,实现实时进度通知等高级功能。