1. SSE 协议原理概述
1.1 什么是 SSE 协议?
SSE(Server-Sent Events,服务器发送事件)是一种通过 HTTP 协议,利用长连接实现服务器推送消息给客户端的机制。与 WebSocket 的双向通信不同,SSE 是单向通信,只允许服务器将数据推送到客户端,适合需要实时推送更新但不需要客户端主动发送数据的场景。
SSE 的工作原理基于以下几点:
- 长连接:客户端与服务器之间会保持一个持久的 HTTP 连接,服务器通过该连接实时推送数据。
- 事件流:数据被分为多个事件(Event),每个事件包含了数据和一些元信息(如事件类型、事件 ID 等),这些事件被客户端接收并处理。
- 自动重连:如果连接中断,客户端会自动尝试重连,保证数据的持续接收。
1.2 SSE 数据格式
SSE 消息遵循特定的格式,通常由多行文本组成。每条消息的格式大致如下:
event: <事件类型> # 可选,表示事件类型
data: <事件数据> # 必选,包含推送的实际数据
id: <事件ID> # 可选,表示事件 ID,便于客户端断线重连时恢复数据
retry: <重连间隔> # 可选,表示重连的时间间隔(单位:毫秒)
2. 在 FastAPI 中实现 SSE 协议
2.1 FastAPI 与 SSE 的基础支持
FastAPI 是一个现代的、快速的 Web 框架,基于 Python 的类型提示和 Starlette 框架实现,原生支持异步编程(async/await)。这使得 FastAPI 非常适合处理实时数据流(如 SSE)等高并发场景。
在 FastAPI 中实现 SSE 需要做的主要工作是:
- 保持 HTTP 长连接:SSE 需要通过长连接(long-lived HTTP connection)来保持客户端与服务器之间的通信。
- 流式响应(Streaming Response):FastAPI 提供了
StreamingResponse类,实现将数据流式发送到客户端,这正是 SSE 的核心。
2.2 FastAPI 实现 SSE 流程详解
-
客户端请求连接:客户端通过
EventSource对象向服务器发起一个 HTTP 请求,该请求将持续保持连接,不会立即关闭。 -
服务器保持长连接:服务器端通过 FastAPI 创建一个异步生成器函数,用于不断生成符合 SSE 协议的数据流。这个生成器函数会使用
yield来逐步返回数据。 -
推送数据给客户端:服务器通过
StreamingResponse类将数据流返回给客户端,设置media_type="text/event-stream",指示这是一个 SSE 响应。 -
客户端接收并处理数据:客户端使用
EventSourceAPI 监听事件,根据推送的数据更新页面内容。
2.3 完整的 FastAPI SSE 实现示例
以下是一个完整的 FastAPI + SSE 的实现代码,包括后端和前端的代码:
后端(FastAPI 实现 SSE)
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
import asyncio
import random
import json
app = FastAPI()
@app.get("/test/sse/")
async def sse(request: Request):
"""
SSE 端点,向客户端推送设备状态更新。
"""
async def event_stream():
while True:
# 检查客户端是否断开连接
if await request.is_disconnected():
print("客户端断开连接")
break
# 模拟设备状态更新
state = "ON" if random.randint(0, 1) == 1 else "OFF"
event_data = {
"event": "update", "state": state}
# 将事件数据按照 SSE 格式返回
yield f"event: {
event_data['event']}\ndata: {
json.dumps(event_data)}\n\n"
# 模拟每 2 秒推送一次状态更新
await asyncio.sleep(2

5678

被折叠的 条评论
为什么被折叠?



