Files
obsidian-notes/InBox/BV1if7E64Ex5-SSE-FastAPI流式响应笔记.md

118 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SSE 到底是什么?用 FastAPI 一次讲透流式响应 | BV1if7E64Ex5
Milky 整理
## 一、三种通信协议对比
| 协议 | 类比 | 特点 |
|------|------|------|
| HTTP | 懒惰的服务员 | 你问一次,他答一次,服务器无法主动推送 |
| SSE | 勤快的服务员 | 只需要开口说一次,他会主动汇报最新进度 |
| WebSocket | 双方都带着对讲机 | 任何一方都可以随时主动说话,完全平等的双向通信 |
## 二、SSE 协议的适用场景
- **HTTP**:必须等模型生成完所有内容才能一次性返回,用户等待时间过长
- **WebSocket**:功能强大但成本高,且大多数 AI 场景中用户不需要主动发消息
- **SSE**:只发起一次请求,服务器边生成边推送,用户实时看到文字逐字出现
## 三、SSE 工作原理详解
### 完整流程
```
客户端 → 普通 HTTP 请求 → 服务器
客户端 ← Content-Type: text/event-stream ← 服务器
客户端 ← Connection: keep-alive ← 服务器
客户端 ← 持续推送事件数据 ← 服务器
客户端 ← event: done / data: [DONE] ← 服务器
```
### HTTP 响应头
```
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
```
### SSE 消息格式
| 字段 | 作用 |
|------|------|
| data | 消息内容 |
| event | 事件类型 |
| id | 消息编号 |
| retry | 断线重连间隔(毫秒) |
每条消息之间用空行分隔。
### 浏览器端接收
```javascript
const source = new EventSource('/stream');
source.onmessage = (event) => {
console.log(event.data);
};
```
## 四、FastAPI 核心前置知识
- 与 Pydantic 深度绑定,自动请求解析和响应序列化
- 自动生成交互式 API 文档(/docs
- 原生支持 async/await 异步编程
## 五、生成器Generator与 yield 关键字
yield 函数的四个特点:
1. 用 yield 代替 return
2. 执行到 yield 暂停并返回值
3. 下次调用从 yield 后继续
4. 按需产生数据,适合流式场景
## 六、完整 FastAPI SSE 实现
### 环境要求
```
FastAPI >= 0.135
```
### 代码
```python
from fastapi import FastAPI
from fastapi.responses import EventSourceResponse
from sse.starlette.sse import ServerSentEvent
from pydantic import BaseModel
app = FastAPI()
class ChatRequest(BaseModel):
message: str
@app.post("/stream")
async def stream_chat(request: ChatRequest):
async for chunk in model_stream(request.message):
if chunk == "[DONE]":
return
yield ServerSentEvent(data=chunk)
```
### 核心公式
```
EventSourceResponse + yield ServerSentEvent
```
## 七、三种协议总结对比
| 协议 | 实现复杂度 | 推送方向 | 适用场景 |
|------|-----------|----------|----------|
| HTTP | ⭐ 最简单 | 仅服务端响应 | 简单的一问一答 |
| SSE | ⭐⭐ 中等 | 服务端持续推送 | AI 流式输出、实时通知 |
| WebSocket | ⭐⭐⭐ 复杂 | 双向通信 | 需要客户端主动发消息的场景 |
──────────────────────────────
Generated by MilkyAi@Bilibili