稀土掘金技术社区 2024年11月30日
还在用轮询、websocket查询大屏数据?sse用起来
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了大屏数据请求的常见方式,包括HTTP轮询、WebSocket和SSE,并详细比较了SSE和WebSocket的优缺点及适用场景。SSE作为一种基于HTTP协议的轻量级技术,更适合于大屏数据查询,例如消息通知、未读消息等;而WebSocket则更适合于双向通信的场景,例如聊天功能。文章还提供了前端和后端代码示例,帮助读者理解SSE的实现方式,以及在开发过程中可能遇到的问题和解决方法。

🤔 **HTTP请求轮询:** 优点是简单易用,传参方便;缺点是数据更新不实时,浪费服务器资源,因为会定时请求数据,即使数据没有更新。

🚀 **WebSocket:** 优点是实现服务器与客户端的长连接,数据更新及时,节约服务器资源;缺点是大材小用,处理心跳、重连等问题相对复杂,通常大屏数据只需要查询数据,不需要发送消息。

💡 **SSE(Server-Sent Events):** 优点是基于HTTP协议,兼容性好,轻量级,使用简单,默认支持断线重连;缺点是原生EventSource不支持设置请求头,需要使用第三方包,后端需要设置响应头。

🔄 **SSE与WebSocket区别:** WebSocket支持双向通信,SSE只支持服务端向客户端发送数据;WebSocket是一种新的协议,SSE基于HTTP协议;SSE默认支持断线重连,WebSocket需要自己实现;WebSocket相对复杂,SSE简单易用。

🎯 **适用场景:** SSE更适合大屏数据查询,如消息通知、未读消息;WebSocket更适合聊天功能等双向通信场景。

原创 Mozambique_Here 2024-11-30 09:03 重庆

点击关注公众号,“技术干货”及时达!

点击关注公众号,“技术干货” 及时达!

常见的大屏数据请求方式

1、http请求轮询:使用定时器每隔多少时间去请求一次数据。优点:简单,传参方便。缺点:数据更新不实时,浪费服务器资源(一直请求,但是数据并不更新)
2、websocket:使用websocket实现和服务器长连接,服务器向客户端推送大屏数据。优点:长连接,客户端不用主动去请求数据,节约服务器资源(不会一直去请求数据,也不会一直去查数据库),数据更新及时,浏览器兼容较好(web、h5、小程序一般都支持)。缺点:有点大材小用,一般大屏数据只需要查询数据不需要向服务端发送消息,还要处理心跳、重连等问题。
3、sse:基于http协议,将一次性返回数据包改为流式返回数据。优点:sse使用http协议,兼容较好、sse轻量,使用简单、sse默认支持断线重连、支持自定义响应事件。缺点:浏览器原生的EventSource不支持设置请求头,需要使用第三方包去实现(event-source-polyfill)、需要后端设置接口的响应头Content-Type: text/event-stream

sse和websocket的区别

    websocket支持双向通信,服务端和客户端可以相互通信。sse只支持服务端向客户端发送数据。

    websocket是一种新的协议。sse则是基于http协议的。

    sse默认支持断线重连机制。websocket需要自己实现断线重连。

    websocket整体较重,较为复杂。sse较轻,简单易用。

Websocket和SSE分别适用于什么业务场景?

根据sse的特点(「轻量、简单、单向通信」)更适用于「大屏」的数据查询,业务应用上查询全局的一些数据,比如「消息通知」「未读消息」等。

根据websocket的特点(「双向通信」)更适用于「聊天功能」的开发

前端代码实现

sse的前端的代码非常简单

 const initSse = () => {
        const source = new EventSource(`/api/wisdom/terminal/stats/change/notify/test`);
        // 这里的stats_change要和后端返回的数据结构里的event要一致
        source.addEventListener('stats_change'function (event: any{
            const types = JSON.parse(event.data).types;        });
        // 如果event返回的是message 数据监听也可以这样监听
        // source.onmessage =function (event) {
        //  var data = 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这个库

 const source = new EventSourcePolyfill(`/api/wisdom/terminal/stats/change/notify/${companyId}`, {
            headers: {
                Authorization: sessionStorage.get(StorageKey.TOKEN) || storage.get(StorageKey.TOKEN),
                COMPANYID: storage.get(StorageKey.COMPANYID),
                COMPANYTYPE1,
                CT13            }        });        
        //其它的事件监听和原生的是一样

后端代码实现

后端最关键的是设置将响应头的「Content-Type」设置为「text/event-stream」「Cache-Control」设置为「no-cache」「Connection」设置为「keep-alive」。每次发消息需要在消息体结尾用"/n/n"进行分割,一个消息体有多个字段每个字段的结尾用"/n"分割。

var http = require("http");
http.createServer(function (req, res{
  var fileName = "." + 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: " + (new Date()) + "\n\n");
    res.write("data: " + (new Date()) + "\n\n");
    interval = setInterval(function () {
      res.write("data: " + (new Date()) + "\n\n");
    }, 1000);
    req.connection.addListener("close"function () {      clearInterval(interval);
    }, false);  }
}).listen(8844"127.0.0.1");

其它开发中遇到的问题

我在开发调试中用的是umi,期间遇到个问题就是sse连接上了但是在控制台一直没有返回消息,后端那边又是正常发出了的,灵异的是在后端把服务干掉的一瞬间可以看到控制台一下接到好多消息。我便怀疑是umi的代理有问题,然后我就去翻umi的文档,看到了下面的东西:

一顿操作之后正常

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

大屏数据 SSE WebSocket HTTP轮询 数据请求
相关文章