3.6 KiB
3.6 KiB
Rust api-server SSE 使用口径(2026-04-22)
日期:2026-04-22
1. 文档目的
这份文档用于冻结 server-rs/crates/api-server 的 SSE 实现口径。
本轮结论调整为:Rust api-server 不再维护自定义 sse.rs 基础设施,统一使用 Axum 内建的 axum::response::sse::{Event, Sse} 能力。
本轮目标只有三个:
- 删除
server-rs/crates/api-server/src/sse.rs自定义模块。 - 把现有 custom world message stream 切到 Axum 官方 SSE 类型。
- 保持现有业务事件协议与“一次性返回完整事件序列”的兼容语义不变。
本轮不做:
- 不改前端消费协议。
- 不把 custom world message stream 当场改成真实逐段 token streaming。
- 不引入跨 crate 的共享 SSE runtime helper。
- 不抽象
reply_delta / session / done / error等业务事件名。
2. 当前问题
上一轮曾在 server-rs/crates/api-server/src/sse.rs 中抽出自定义 SSE helper,用于统一响应头、事件编码、缓冲式输出和实时 writer。
继续保留这套自定义模块的问题是:
- Axum 已经提供
Sse<Event>、Event::json_data(...)和标准 SSE body 编码。 - 自定义文本编码需要自行维护换行、JSON 序列化、响应头等细节。
- 后续真流式接口如果继续沿用自定义 writer,会和 Axum 官方生态产生重复抽象。
- 当前项目已经以 Axum 作为 Rust HTTP 框架,优先使用框架内建能力更简单。
3. 统一实现口径
Rust api-server 的 SSE 路由统一使用:
use axum::response::sse::{Event, Sse};
有限事件序列使用:
let stream = tokio_stream::iter(events);
Sse::new(stream).into_response()
实时流式接口后续直接使用:
Sse::new(event_stream)
如需保持长连接,可在真实长流接口中追加:
.keep_alive(axum::response::sse::KeepAlive::default())
4. custom world message stream 边界
POST /api/runtime/custom-world/agent/sessions/:sessionId/messages/stream 当前继续保持 Stage 8 文档冻结的最小语义:
- 业务层先完成 deterministic 写表。
- 读取最新 session snapshot。
- 组装
reply_delta。 - 组装
session。 - 组装
done。 - 通过 Axum
Sse返回完整事件序列。
本轮只替换传输层实现,不改变事件顺序、事件名和 payload 结构。
5. 响应头说明
Axum Sse 默认写入:
Content-Type: text/event-streamCache-Control: no-cache
当前不再额外写入自定义 X-Accel-Buffering: no helper。
原因:
- 本轮目标是移除项目自定义 SSE 模块,避免继续维护传输层封装。
- 当前 custom world stream 仍是短生命周期的兼容事件序列,不是长时间 token streaming。
- 如果未来某条真实长流接口需要反向代理禁用缓冲,应在该路由或统一 HTTP 中间件层显式评估,而不是恢复自定义 SSE 编码器。
6. 验收标准
当以下条件满足时,本轮视为完成:
api-server/src/sse.rs已删除。api-server/src/main.rs不再声明mod sse;。custom_world.rs不再依赖crate::sse::SseEventBuffer。- custom world message stream 使用 Axum
Sse<Event>构造响应。 - 为旧自定义 writer 引入的
bytes、tokio::syncfeature 等依赖已清理。 cargo fmt -p api-server通过。cargo check -p api-server通过。npm run check:encoding通过。
7. 一句话结论
Rust api-server 的 SSE 能力以 Axum 内建 Sse<Event> 为唯一实现入口,不再保留项目自定义 sse.rs 模块;当前 custom world stream 只替换传输层,不改变业务协议。