@microsoft/fetch-event-source
@microsoft/fetch-event-source,是微软开发的一个库,用于通过 Fetch API 实现 SSE 的流式数据传输。它封装了请求发送、消息接收和连接恢复的逻辑,非常适合流式数据的处理。
主要参数:
- method: HTTP 方法,通常为
POST。 - headers: 请求头信息,通常需要指定
Content-Type为application/json。 - body: 请求体内容,可以根据需求传递给后端。
- onmessage: 处理流式消息的回调函数,每当服务器发送一条消息时会调用。
- onclose: 服务器关闭连接时的回调。
- onerror: 出现错误时的回调。
安装库:npm install @microsoft/fetch-event-source
客户端
import React, { FC, useEffect, useState } from 'react';
import { fetchEventSource } from '@microsoft/fetch-event-source';
cosnt App =()=>{
const [data, serData] = useState([]);
const fun = ()=>{
fetchEventSource('/api/sse',{
method:"POST",
headers: { 'Content-Type': 'application/json', },
body: JSON.stringify({ query: '参数传递' }),
onmessage(event){
// 这里可以根据接收到的流式数据更新到界面需要的地方
setData(prevData => [...prevData, JSON.parse(res.data)]);
},
// 报错
onerror(err) {
// 报错信息
console.error('Error:', err);
},
// 服务器关闭连接
onclose() {
console.log('服务器关闭连接');
},
});
};
return<>
<div style={{width: '300px', height: '100px', overFlow: 'scroll'}}>
{data.map(item => ( <div>{item.name}</div> ))} </div>
</>
};
服务端
const Koa = require('koa');
const Router = require('koa-router');
const { PassThrough } = require('stream')
//路径管理
const path = require('path');
const static = require('koa-static');
const main = static(path.join(__dirname) + '/www/');
const app = new Koa();
const router = new Router();
app.use(main)
// 发送消息
const sendMessage = async (stream) => {
const data = [
{
name: 'Page A',
uv: 4000,
pv: 2400,
amt: 2400,
},
{
name: 'Page B',
uv: 3000,
pv: 1398,
amt: 2210,
},
{
name: 'Page C',
uv: 2000,
pv: 9800,
amt: 2290,
},
{
name: 'Page D',
uv: 2780,
pv: 3908,
amt: 2000,
},
{
name: 'Page E',
uv: 1890,
pv: 4800,
amt: 2181,
},
{
name: 'Page F',
uv: 2390,
pv: 3800,
amt: 2500,
},
{
name: 'Page G',
uv: 3490,
pv: 4300,
amt: 2100,
},
];
// 循环上面数组: 推送数据、休眠 2 秒
for (const value of data) {
stream.write('data: ' + JSON.stringify(value) + '\n\n');; // 写入数据(推送数据)
await new Promise((resolve) => setTimeout(resolve, 2000));
};
};
// SSE 路由处理
router.get('/api/sse', async (ctx, next) => {
// 设置响应头
ctx.set({
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 2. 创建流、并作为接口数据进行返回
const stream = new PassThrough();
ctx.body = stream;
ctx.status = 200;
// 3. 推送流数据
sendMessage(stream, ctx);
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3005, () => {
console.log('Server is running on http://localhost:3005');
});