FastAPI 支持通过 StreamingResponse 实现流式响应。还有一个 Starlette 实现的服务器发送事件(EventSourceResponse)可以在这里找到:here。问题是,它们有何不同?
FastAPI 中的 StreamingResponse 与 Starlette 中的 EventSourceResponse 的对比StreamingResponse 是 FastAPI 中的一种响应类型,用于处理流式数据。相比之下,EventSourceResponse 是 Starlette 中的一种响应类型,主要用于实现服务器发送事件 (SSE) 功能。这里,我们将探讨这两种响应类型的异同。
关于StreamingResponse的简述(流响应)来自 FastAPI 文档: 如下:
这很模糊,没什么帮助 -_-。如果我们来看一看上面定义的 FastAPI 应用程序的响应网络请求,看起来是这样的。
有一件事特别显眼。Transfer-Encoding: chunked.
如果我们看一下 Mozilla 开发者网站上的相关文档:
[ _chunked_](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#chunked)
数据以一系列块的形式传输。在这种情况下,会省略
[_Content-Length_]
头部字段,在每个块的开始需添加当前块长度的十六进制表示,后面跟着'_\r\n_'
,紧随其后是块自身,再跟一个'_\r\n_'
。唯一的区别是其长度为零。其后跟随一个尾部,由一个(可能为空的)头部字段序列组成。
这里的关键点是,当服务器在发送第一个响应数据块前还不知道内容长度时,可以使用 Transfer-Encoding: chunked 头部。很明显,这就是 StreamingResponse 的全部操作,它只是开始发送带有 Transfer-Encoding 标头为 chunks 的响应数据块,并不再指定 content-length。
来自sysid blog的 EventSourceResponse 描述:
服务器发送事件(SSE)是 HTML 标准的一部分,而不是直接属于 HTTP 标准1。它们定义了一个协议,该协议对 HTTP 层是透明的,不会扰乱任何下层协议。
在核心上,SSE 实际上只是一个
_Content-Type
头,它告诉客户端响应将分块传送。它还通知浏览器,每当接收到新的数据块时,浏览器就将这些数据块暴露给代码,而不是等到整个请求完成,就像 WebSocket 的帧一样2。
有点帮助,要点是:
- SSE 只是一个
_Content-Type_
事件流头。SSE 即 Server-Sent Events。
我们可以构建一个使用 EventSourceResponse: 的 FastAPI 应用:
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import json
from sse_starlette import EventSourceResponse
app = FastAPI()
def fake_video_streamer():
try:
for i in range(10):
yield {
"data": json.dumps(f"数据点 {i}"),
"event": "数据段",
}
yield {"event": "完成"}
except:
yield {
"event": "错误",
"data": json.dumps(
{"HTTP状态码": 500, "信息": "服务器内部错误"}
),
}
raise
@app.get("/")
async def main():
return EventSourceResponse(fake_video_streamer())
我们来看看网络的响应头信息:
最显眼的是:
- 内容类型为:
[text/event-stream](https://html.spec.whatwg.org/multipage/iana.html#text/event-stream)
在内容类型中添加 MIME 类型,表示文档、文件或字节集合的类型和格式。由于它是 HTML 标准的一部分,因此很容易编写客户端代码通过定义的接口(比如)读取服务器发送的带有 MIME 类型 [text/event-stream](https://html.spec.whatwg.org/multipage/iana.html#text/event-stream)
的事件(分块响应流) → EventSource。
这里有这样一个很棒的关于使用React.js处理SSE的gist:这个链接。
共同学习,写下你的评论
评论加载中...
作者其他优质文章