使用 msw 模拟 Server-Sent Events(SSE)
原文由 Alex O'Callaghan 于 发布,订阅该博客
更新:MSW 已新增对模拟 Server-Sent Events 的一等支持——本文也获得了署名致谢,不过现在建议你直接查阅 MSW 文档。
Server-sent events 允许服务端向前端应用推送事件流。它与 WebSocket 类似,但仅提供从服务端到客户端的单向连接。
像 ChatGPT 这样的生成式 AI 解决方案会利用 Server-sent events,在大语言模型生成响应的过程中以流的形式实时推送到客户端。随着生成式 AI 应用的普及,如何处理这类流式响应成为需要克服的一大挑战,它与典型的 REST API 有所不同。
Mock Service Worker 是一款流行的工具,用于编写可在不同框架、工具和环境中复用的 JavaScript API mock。在 Mintel,我们使用 msw 为 Storybook、单元测试和其他开发环境编写 mock。
msw 已支持模拟 SSE 事件,而 对 WebSocket 的支持仍处于 Beta 阶段。例如,假设有如下用于建立 Server-Sent Events 连接的前端代码:
const source = new EventSource("http://example.com/stream");
source.onmessage = (event) => {
console.log(`Message: ${event.data}`);
};你可以编写如下 msw mock 处理器:
import { http, HttpResponse } from "msw";
const encoder = new TextEncoder();
const handler = http.get('http://example.com/stream', () => {
const stream = new ReadableStream({
start(controller) {
controller.enqueue(
encoder(
`event:some-event\ndata:some data\n\n`
)
);
controller.close();
},
});
return new HttpResponse(stream, {
headers: {
"Content-Type": "text/event-stream",
}.
});
});这个 mock 会返回单个 some-event 事件,其 event.data 中包含 "some data"。每条消息都应包含表示字段与值的多行文本,字段名与值之间用冒号分隔。消息之间则以一对换行符分隔。你可以进一步了解事件流消息格式。
你还可以进一步了解使用 msw 实现流式响应,其中包含如何通过延迟流来处理响应以模拟延迟响应的示例。
如果你遇到了 EventSource API 的一些限制,例如无法为身份验证提供自定义请求头,也可以了解一下 fetch-event-source,因为这种模拟方式对两者都适用。
随机一篇博客
评论
登录后参与讨论