demo 示例
demo 思路
- 监听端口启动服务端,处理不同的请求路径,sse 路径设置相关的响应头。
- 客户端创建 EventSource 对象,传入服务端的服务端推送请求路径。
- 接受到结束消息(这里取空消息为结束标识)时,调用 close 关闭连接。
服务端相关操作
- 使用 node 搭建服务器(基本的服务创建套路)
import http from "http";
const port = 3006;
const server = http.createServer((request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");
routerHandle(request.url || "/", response);
});
- 路由处理函数
const routerHandle = (
url: string,
response: http.ServerResponse<http.IncomingMessage>
) => {
switch (url) {
case "/":
break;
case "/sse":
response.writeHead(200, {
connection: "keep-alive",
"cache-control": "no-cache",
"content-type": "text/event-stream",
});
recursiveGenString(15, response);
break;
default:
break;
}
};
- sse 响应延迟以及内容 mock
const LOREM_STRING = "这是一段测试字符串";
const generateWord = (): string => {
const randomWordsCount = parseInt(
String(Math.random() * LOREM_STRING.length)
);
const word = LOREM_STRING.slice(0, randomWordsCount);
return word;
};
const recursiveGenString = (
maxTimes: number,
response: http.ServerResponse<http.IncomingMessage>
) => {
let count = 0;
const get = () => {
return new Promise((resolve, reject) => {
const responseTime = parseInt(String(Math.random() * 3)) * 1000;
setTimeout(() => {
const responseContent = generateWord();
// 模拟结束
if (count++ >= maxTimes) {
response.end(`data:\n\n`);
return;
} else {
response.write(`data: ${responseContent || "。"}\n\n`);
resolve(1);
}
}, responseTime);
}).then(() => {
get();
});
};
get();
};
客户端相关操作
- 创建 EventSource 对象
const eventSource = new EventSource("http://127.0.0.1:3006/sse");
- 处理消息
eventSource.onmessage = (e) => {
console.log(">>", e);
if (!e.data) {
eventSource.close();
return;
}
sseContainer.innerHTML += `${e.data}`;
};
完整代码
ProgrammeLab/event-source-demo: client EventSource & server SSE demo (github.com)