sse实现消息实时推送, 前端如何处理流式数据

前两天会上有一个需求, 就是某个数据发生变化了, 需要给用户提示一下, 这个时候呢, 我们就需要使用SSE服务了

那么, 什么是SSE呢?

SSE全称叫做: Server-Sent Events, 该服务是一种服务器向客户端推送实时更新的机制模式, Http协议是无法实现服务端向客户端主动推送消息, 但是呢, 可以向客户端声明, 要发送流信息, 所以该服务就是利用这个机制, 向客户端推送信息

在之前, 我们写过WebSocket的小案例, 其实两者作用相似, 但是也有很多不同, 上面说了SSE基于Http协议, WS就是一个独立协议, 我们都知道WS是全双工通道, 功能相对强大一点, 可以双向通信, 但是SSE是单向通道, 只能实现服务器向客户端推送消息, WS这么厉害, 是不是SSE就不行了, SSE也有WS不可比的优点, 比如: SSE支持断线重连, 使用相对简单等等

接下来, 我们写一个小案例, 不断向客户端推送递增的数据,客户端判断为50,提示消息

首先, 我们创建一个js文件, 其中引入Http模块

var http = require(“http”);
创建Http服务器

http.createServer(function (req, res) { … }).listen(8844, “127.0.0.1”);
创建的时候,我们指定一个请求路径, 随后需要我们设置响应头, 指定内容类型, 不缓存, 保持连接, 并设置跨域访问

res.writeHead(200, {
“Content-Type”: “text/event-stream”,
“Cache-Control”: “no-cache”,
Connection: “keep-alive”,
“Access-Control-Allow-Origin”: “*”,
});
指定请求地址是/sse, 我们判断一下, 如果请求的地址是/sse, 我们就创建一个定时器, 每秒向客户端推送一个递增的数字

let num = 1;
let interval = null;
if (fileName === “./sse”) {
interval = setInterval(function () {
res.write(“data: ” + num + “\n\n”);
num++;
}, 1000);
}
如果, 客户端关闭了链接, 我们也需要移除定时器, 并将数字置空, 现在我们注册一个close事件, 用于监听前端关闭连接

req.socket.on(“close”, function () {
clearInterval(interval);
num = 1;
});
现在, 请求服务部分我们算是写完了, 前端就更简单了

当我们使用SSE时, 需要我们获取一个 EventSource 实例, 用于向服务器发起连接

对于EventSource, 大家可以参考MDN

https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource
看最前面两句介绍, 是这样说的

EventSource 接口是Web内容与服务器发送事件通信的一个接口, 首先是用于通信的, 当我们实例化 EventSource, 就会对服务器开启一个持久化的链接, 并以 text/event-stream 格式发送事件, 那什么时候关闭呢? 就是我们调用EventSource.close() 的时候

看到此处, 大家估计会对前端处理SSE有一个印象了

那我们来实现一下, 运行一下http服务

node server.js
新建一个html文件, 创建两个按钮, 用于链接的建立和关闭

用户点击开启链接, 我们就实例化 EventSource 实例, 来建立与服务器的连接

现在, 我们点击了按钮, 我们会发现建立连接了, 服务器在不断的推送递增数据, 这样写, 就完了吗, 肯定不行的, 后端返回的数据, 我们怎么才能拿到呢?

接下来, 我们取一下服务器返回的数据, 这时, 就需要查看 EventSource 的事件了, 它提供了三个事件, 分别是open, message, error, 那么这三个事件分别是什么意思呢?我们一一来介绍一下, 当建立的链接时候, 会触发open事件, 正在通信会触发, 服务器向客户端推送信息时, 触发message事件, 当通信出错时, 会触发error事件

我们再次点击一下按钮, 看看打印结果

我们可以看到, 有打印信息, 取到值, 应该是 event.data, 现在, 就可以判断data等于多少, 我们弹出弹窗进行提示就可以了

我们看一下效果

这样, 我们的功能就实现了

今天, 就讲解到这里

我们下期见

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/422827.html

联系我们
联系我们
分享本页
返回顶部