SSE(Server-Sent Events,服务器发送事件)让服务端通过一条保持打开的 HTTP 连接,连续向客户端发送事件。它适合任务进度、日志和通知等服务器单向推送场景。

为什么普通响应不够用

普通 HTTP 请求通常只返回一次结果:
请求 --------> 处理 --------> 一次性响应
文章解析可能持续几十秒。若等待最终响应,客户端不知道任务是否仍在运行。SSE 可以在处理期间不断发送状态:
请求 --------> progress: 10% --> progress: 40% --> completed

SSE 如何工作

服务端返回 Content-Type: text/event-stream,并保持连接。事件由文本行组成,事件之间以空行分隔:
event: progress
data: {"progress":40,"message":"Generating explanations"}

event: completed
data: {"article_id":42}

客户端逐个读取事件并更新界面,直到任务完成、失败或连接关闭。

与其他方式的区别

方式通信方向适合场景代价
轮询客户端反复请求简单、低频状态检查有延迟且产生重复请求
SSE服务端持续推送给客户端进度、通知、日志主要是单向通信
WebSocket双向持续通信聊天、协作编辑、实时控制协议与连接管理更复杂
RakuLLApp 只需要服务端推送处理进度,因此 SSE 比 WebSocket 更直接。

RakuLLApp 的任务流程

  1. 客户端提交上传或重新生成请求。
  2. Controller 创建内存任务并立即返回 task_id
  3. 客户端订阅 GET /api/tasks/{id}/progress
  4. Controller 编排 Agent 和 Model,并通过 SSE 推送进度。
  5. 客户端收到 completedfailed 后结束监听。
反向代理若缓冲响应,客户端会在最后一次性收到所有事件,看起来就像 SSE 没有工作。进度端点必须关闭代理缓冲和缓存。
SSE 连接也可能因网络中断而关闭,所以客户端仍需处理超时、失败和重试。当前项目的完整调用顺序见 数据流