还在用轮询、websocket查询大屏数据?sse用起来
点击关注公众号,“技术干货”及时达!
常见的大屏数据请求方式1、http请求轮询:使用定时器每隔多少时间去请求一次数据。优点:简单,传参方便。缺点:数据更新不实时,浪费服务器资源(一直请求,但是数据并不更新)2、websocket:使用websocket实现和服务器长连接,服务器向客户端推送大屏数据。优点:长连接,客户端不用主动去请求数据,节约服务器资源(不会一直去请求数据,也不会一直去查数据库),数据更新及时,浏览器兼容较好(web、h5、小程序一般都支持)。缺点:有点大材小用,一般大屏数据只需要查询数据不需要向服务端发送消息,还要处理心跳、重连等问题。3、sse:基于http协议,将一次性返回数据包改为流式返回数据。优点:sse使用http协议,兼容较好、sse轻量,使用简单、sse默认支持断线重连、支持自定义响应事件。缺点:浏览器原生的EventSource不支持设置请求头,需要使用第三方包去实现(event-source-polyfill)、需要后端设置接口的响应头Content-Type: text/event-streamsse和websocket的区别websocket支持双向通信,服务端和客户端可以相互通信。sse只支持服务端向客户端发送数据。websocket是一种新的协议。sse则是基于http协议的。sse默认支持断线重连机制。websocket需要自己实现断线重连。websocket整体较重,较为复杂。sse较轻,简单易用。Websocket和SSE分别适用于什么业务场景?根据sse的特点(「轻量、简单、单向通信」)更适用于「大屏」的数据查询,业务应用上查询全局的一些数据,比如「消息通知」、「未读消息」等。
根据websocket的特点(「双向通信」)更适用于「聊天功能」的开发
前端代码实现sse的前端的代码非常简单
constinitSse=()={
constsource=newEventSource(`/api/wisdom/terminal/stats/change/notify/test`);
//这里的stats_change要和后端返回的数据结构里的event要一致
source.addEventListener('stats_change',function(event:any){
consttypes=JSON.parse(event.data).types;
//如果event返回的是message数据监听也可以这样监听
//source.onmessage=function(event){
//vardata=event.data;
//
//下面这两个监听也可以写成addEventListener的形式
source.onopen=function(){
console.log('SSE连接已打开');
//处理连接错误
source.onerror=function(error:any){
console.error('SSE连接错误:',error);
setSseSource(source);
//关闭连接
sseSource.close();
这种原生的sse连接是不能设置请求头的,但是在业务上接口肯定是要鉴权需要传递token的,那么怎么办呢?我们可以使用event-source-polyfill这个库
constsource=newEventSourcePolyfill(`/api/wisdom/terminal/stats/change/notify/${companyId}`,{
headers:{
Authorization:sessionStorage.get(StorageKey.TOKEN)||storage.get(StorageKey.TOKEN),
COMPANYID:storage.get(StorageKey.COMPANYID),
COMPANYTYPE:1,
CT:13
}
//其它的事件监听和原生的是一样
后端代码实现后端最关键的是设置将响应头的「Content-Type」设置为「text/event-stream」、「Cache-Control」设置为「no-cache」、「Connection」设置为「keep-alive」。每次发消息需要在消息体结尾用"/n/n"进行分割,一个消息体有多个字段每个字段的结尾用"/n"分割。
varhttp=require("http");
http.createServer(function(req,res){
varfileName="."+req.url;
if(fileName==="./stream"){
res.writeHead(200,{
"Content-Type":"text/event-stream",
"Cache-Control":"no-cache",
"Connection":"keep-alive",
"Access-Control-Allow-Origin":'*',
res.write("retry:10000\n");
res.write("event:connecttime\n");
res.write("data:"+(newDate())+"\n\n");
res.write("data:"+(newDate())+"\n\n");
interval=setInterval(function(){
res.write("data:"+(newDate())+"\n\n");
},1000);
req.connection.addListener("close",function(){
clearInterval(interval);
},false);
}
}).listen(8844,"127.0.0.1");
其它开发中遇到的问题我在开发调试中用的是umi,期间遇到个问题就是sse连接上了但是在控制台一直没有返回消息,后端那边又是正常发出了的,灵异的是在后端把服务干掉的一瞬间可以看到控制台一下接到好多消息。我便怀疑是umi的代理有问题,然后我就去翻umi的文档,看到了下面的东西:
一顿操作之后正常
点击关注公众号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线