EventSource
- 服务端主动推动数据
EventSource 是服务器主动向客户端推送数据的一个网络事件接口。一个 EventSource 实例会对 HTTP 服务开启一个持久化的连接,以 text/event-stream 格式发送事件, 会一直保持开启直到被要求关闭。
服务端
// node 的实现
// 单边通讯,服务器主动推送客户端
const fs = require("fs");
const http = require("http");
let server = http.createServer((req, res) => {
let url = req.url;
if (url === "/") {
// 这个路由主要是显示界面(当然如果不需要 node 加载 html 文件,也可以不用这个路由)
res.setHeader("Content-Type", "text/html;charset=utf-8");
let rStream = fs.createReadStream("./index.html");
rStream.pipe(res);
} else if (url === "/sse") {
// SSE 接口
// 如果页面的打开形式不是 通过当前node 环境(非同源),那么设置允许跨域
res.setHeader("Access-Control-Allow-Origin", "*");
// 设置成为 text/event-stream 是关键
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
setInterval(() => {
// 不能使用 end ,因为 end 直接就断开连接了。而我们的需求是长连接
// data: 数据开始标志
// \r\n\r\n 数据结束标志
res.write("data:" + new Date() + "\r\n\r\n");
}, 1000);
}
});
server.listen(3001);
console.log("this server is listening on port 3001");
客户端
<html>
<body>
<h1>
SSE 案例
</h1>
<p id="info"></p>
<button onclick="cls()">关闭连接</button>
<script>
let source = new EventSource("http://127.0.0.1:3001/sse");
// 如果 当前页面是通过 node 环境呈现,不需要跨域的话,也可以这样写
// let source = new EventSource("/sse");
source.onopen = function () {
console.log("连接成功");
// 0 connecting 正在连接
// 1 open 已打开
// 2 closed 已关闭
// console.log(source.readyState); 查看状态
};
// 如果有数据发送过来会触发 message 事件
source.onmessage = function (e) {
console.log(e.data);
document.getElementById("info").innerHTML = e.data;
};
// 如果出现错误
source.onerror = function (err) {
console.log(err);
return;
};
function cls() {
// 关闭连接
source.close();
}
</script>
</body>
</html>