LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

还在用轮询吗,SSE服务端推送实现页面实时更新

freeflydom
2023年6月25日 8:55 本文热度 703

背景

最近开发一个页面碰到一个需求,需要对部分数据需要实时更新状态,面对这样子的场景,我们通常有以下几个方案:

  • 轮询,利用setTimeout定时轮询

  • WebSocket,利用长链接保持与服务通讯

  • SSE,服务端推送机制

是什么

我们先简单认识一下这三者的区别:

轮询

轮询就是利用setTimeout的定时器,定时向服务器发起请求,代码如下:

let timeout = 0;

functon rollRequest(requestFunc, times, immediately){

    if(timeout !== 0){

        clearTimeout(timeout);

    }


    if(immediately){

        requestFunc && requestFunc();

    }


    timeout = setTimeout(()=>{

        requestFunc && requestFunc();

        rollRequest(requestFunc, times, false);

    }, times);

}

缺点

  • 无用请求过多,可能每次请求返回的内容都是相同

  • 实时性不可控,如果内容更新了,但是页面无法及时更新

WebSocket

针对上面轮询的缺点,WebSokcet长链接就能很好解决,如:

  • 建立链接后,当服务器发现数据发生变化后才返回

  • 可控性高,客户端和服务端都可以互相通信

具体实现代码如下:


// 客户端

const ws = new WebSocket(`wss://127.0.0.1:8081`);


ws.send("这是一条消息:" + count);


// 监听消息

ws.onmessage = function (event) {

  console.log(event.data);

}

// 关闭连接

ws.close();


// 服务端

var WebSocketServer = require('ws').Server,

wss = new WebSocketServer({ port: 8181 });

wss.on('connection', function (ws) {

    console.log('client connected');

    ws.on('message', function (message) {

        console.log(message);

    });

});

缺点

可能实现方案对于一个页面数据更新有点太重了,主要包括以下几点:

  • 需要有完整链路认证,如:鉴权、登录等

  • 心跳机制实现,前后端都需要设置

  • 前后端需要规定数据返回规范

  • 服务端需要日志记录

SSE服务端推送

SSE全称Server-sent Events,是HTML 5 规范的一个组成部分,它主要由两部分组成:

  • 第一部分是服务端和浏览器的通讯协议

  • 第二部分是前端需要利用EventSource去监听返回数据

对比WebSocket:

SSEWebSocket
单向:仅服务端能发送消息双向:客户端、服务端双向发送
仅文本数据二进制、文本都可
常规HTTP协议WebSocket协议


实现一个SSE代码如下: 

浏览器:


<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>SSE Demo测试</title>

</head>

<body>

    <h3>SSE返回内容</h3>

    <div id="app"></div>

    <script>

        const eventSource = new EventSource('http://localhost:3000/sse');

        eventSource.onmessage = (event) => {

            document.getElementById('app').innerHTML = document.getElementById('app').innerHTML + `<p>${event.data}</p>`;

        }

    </script>

</body>

</html>


服务端:

const http = require('http')

const fs = require('fs')


// create a server

const server = http.createServer()


// 监听路由

server.on('request', (req, res) => {

    console.log('request', req.url)

    if (req.url === '/sse') {

        // Set CORS headers

        res.setHeader('Access-Control-Allow-Origin', '*')

        res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')

        res.setHeader('Access-Control-Allow-Headers', 'Content-Type')


        // Set SSE headers

        res.setHeader('Content-Type', 'text/event-stream')

        res.setHeader('Cache-Control', 'no-cache')


        // Send a ping approx every 2 seconds

        res.write("retry: 10000\n\n");

        res.write("event: connecttime\n\n");

        res.write("data: 第一次发送:" + (new Date()) + "\n");


        // 模拟收到消息推送给客户端

        interval = setInterval(function () {

            res.write("data: 后续更新" + (new Date()) + "\n\n");

        }, 5000);

    }

    if (req.url === '/index.html' || req.url === '/') {

        // 如果是html文件,返回html文件

        res.setHeader('Content-Type', 'text/html')

        const html = fs.readFileSync('./public/index.html');

        res.end(html)

    }

})


// Listen

server.listen(3000, () => {

    console.log('Server started on port 3000')

})

缺点

  • 兼容性问题,但是目前绝大部分浏览器是支持的,如果不支持可以采用降级方案——轮询

  • 会长期占用一个http链接,

    • 可能会导致浏览器(chrome最大http请求数是6)无法发起其他请求,这里注意是一个坑,需要设置一个超时时间,如果长时间无返回数据更新可以关闭链接

    • 解决方案,升级到http2协议可解决http请求数限制问题,放到后面《如何搭建http2网站》讲解

  • 客户端无法主动向服务器发起请求,可能造成后续问题定位难点

总结

前端实时更新需求,有多个解决方案,下面进行总结:

  • 目前最常用的轮询,是最稳定的,但是却无法做到实时

  • WebSocket可以实时,但是需要服务端和客服端长期保持一致,如果哪一方断了将无法继续

  • SSE是服务推送,可以满足大部分场景,但是也需要谨慎使用,避免占用过多链接导致其他无法发送请求

参考资料

数据不够实时:试试长连接?


原文链接



该文章在 2023/6/25 8:55:29 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved