modify: 流式输出

This commit is contained in:
2026-08-21 14:39:11 +08:00
parent d8230bc0ca
commit 6dbdce177b
3 changed files with 123 additions and 18 deletions
+26
View File
@@ -118,6 +118,7 @@ async def add(request: AddGetRequest) -> AddGetResponse:
| `subject` | `str` | Zenoh 主题(必需),如 `"example.add"` |
| `method` | `str` | HTTP 方法:`"GET"` / `"POST"` / `"MQTT"` |
| `response_model` | `type[BaseModel]` | Pydantic 响应模型类 |
| `stream` | `bool` | 流式端点:函数返回生成器,框架逐块多回复推送(默认 `false`) |
**装饰器行为**:
@@ -127,6 +128,31 @@ async def add(request: AddGetRequest) -> AddGetResponse:
| `POST` | JSON body | 自动绑定到 Pydantic 模型 |
| `MQTT` | MQTT payload JSON | 同 POST |
### 流式端点(SSE 多回复)
`@rpc_method(..., stream=True)` 的函数返回**生成器**(async / sync 均可),框架自动将每个
`yield` 的 dict 作为独立 Zenoh 回复块推送(Query/Reply 原生多回复),网关以 SSE
(`text/event-stream`)逐块转发给 HTTP 客户端。无需端口、进程或新依赖:
```python
@rpc_method(subject="example.stream_chat", method="POST", stream=True)
async def stream_chat(prompt: str = "你好", tokens: int = 10):
for i in range(tokens):
await asyncio.sleep(0.05) # 模拟逐 token 生成
yield {"token": f"{prompt}·{i + 1}", "index": i}
yield {"done": True}
```
**协议约定**(框架自动处理,插件无需关心底层实现):
- 生成器正常结束 = 流结束。**没有协议层结束哨兵**;`{"done": True}` 这类字段只是业务标记
- 生成器中途异常 → 框架发送 `{"error": ...}` 收尾块后停流
- 客户端断开 / 查询被网关放弃 → 逐块 reply 失败时框架立即停流,避免 Worker 空转
- 每个块必须是可 JSON 序列化的对象,单块建议小于 64KB(zenoh 消息上限内)
**网关侧配合**:对应 TOML 方法节声明 `stream = true` 并配大 `timeout`(流总寿命上限),
详见网关仓库 README「流式端点(SSE)」。非流式端点(不声明 `stream`)行为完全不变。
### 请求信封协议
Worker 运行时收到的请求负载统一为信封结构(网关 HTTP 路由 / MQTT Bridge / `chongming-request` Client 自动组装):