91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

還在用輪詢嗎,SSE服務(wù)端推送實現(xiàn)頁面實時更新

freeflydom
2023年6月25日 8:55 本文熱度 1506

背景

最近開發(fā)一個頁面碰到一個需求,需要對部分?jǐn)?shù)據(jù)需要實時更新狀態(tài),面對這樣子的場景,我們通常有以下幾個方案:

  • 輪詢,利用setTimeout定時輪詢

  • WebSocket,利用長鏈接保持與服務(wù)通訊

  • SSE,服務(wù)端推送機制

是什么

我們先簡單認(rèn)識一下這三者的區(qū)別:

輪詢

輪詢就是利用setTimeout的定時器,定時向服務(wù)器發(fā)起請求,代碼如下:

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);

}

缺點

  • 無用請求過多,可能每次請求返回的內(nèi)容都是相同

  • 實時性不可控,如果內(nèi)容更新了,但是頁面無法及時更新

WebSocket

針對上面輪詢的缺點,WebSokcet長鏈接就能很好解決,如:

  • 建立鏈接后,當(dāng)服務(wù)器發(fā)現(xiàn)數(shù)據(jù)發(fā)生變化后才返回

  • 可控性高,客戶端和服務(wù)端都可以互相通信

具體實現(xiàn)代碼如下:


// 客戶端

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


ws.send("這是一條消息:" + count);


// 監(jiān)聽消息

ws.onmessage = function (event) {

  console.log(event.data);

}

// 關(guān)閉連接

ws.close();


// 服務(wù)端

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);

    });

});

缺點

可能實現(xiàn)方案對于一個頁面數(shù)據(jù)更新有點太重了,主要包括以下幾點:

  • 需要有完整鏈路認(rèn)證,如:鑒權(quán)、登錄等

  • 心跳機制實現(xiàn),前后端都需要設(shè)置

  • 前后端需要規(guī)定數(shù)據(jù)返回規(guī)范

  • 服務(wù)端需要日志記錄

SSE服務(wù)端推送

SSE全稱Server-sent Events,是HTML 5 規(guī)范的一個組成部分,它主要由兩部分組成:

  • 第一部分是服務(wù)端和瀏覽器的通訊協(xié)議

  • 第二部分是前端需要利用EventSource去監(jiān)聽返回數(shù)據(jù)

對比WebSocket:

SSEWebSocket
單向:僅服務(wù)端能發(fā)送消息雙向:客戶端、服務(wù)端雙向發(fā)送
僅文本數(shù)據(jù)二進(jìn)制、文本都可
常規(guī)HTTP協(xié)議WebSocket協(xié)議


實現(xiàn)一個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返回內(nèi)容</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>


服務(wù)端:

const http = require('http')

const fs = require('fs')


// create a server

const server = http.createServer()


// 監(jiān)聽路由

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: 第一次發(fā)送:" + (new Date()) + "\n");


        // 模擬收到消息推送給客戶端

        interval = setInterval(function () {

            res.write("data: 后續(xù)更新" + (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鏈接,

    • 可能會導(dǎo)致瀏覽器(chrome最大http請求數(shù)是6)無法發(fā)起其他請求,這里注意是一個坑,需要設(shè)置一個超時時間,如果長時間無返回數(shù)據(jù)更新可以關(guān)閉鏈接

    • 解決方案,升級到http2協(xié)議可解決http請求數(shù)限制問題,放到后面《如何搭建http2網(wǎng)站》講解

  • 客戶端無法主動向服務(wù)器發(fā)起請求,可能造成后續(xù)問題定位難點

總結(jié)

前端實時更新需求,有多個解決方案,下面進(jìn)行總結(jié):

  • 目前最常用的輪詢,是最穩(wěn)定的,但是卻無法做到實時

  • WebSocket可以實時,但是需要服務(wù)端和客服端長期保持一致,如果哪一方斷了將無法繼續(xù)

  • SSE是服務(wù)推送,可以滿足大部分場景,但是也需要謹(jǐn)慎使用,避免占用過多鏈接導(dǎo)致其他無法發(fā)送請求

參考資料

數(shù)據(jù)不夠?qū)崟r:試試長連接?


原文鏈接



該文章在 2023/6/25 8:55:29 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产精品精 | 91精品视频在线 | 国自产拍偷拍福 | 欧美在线日韩精品 | 精品免费成人 | 国产绿帽| 欧美性受xxxx| 国产激情在线观看 | 国内精品露脸在线 | 福利研究所导航 | 国产黑丝在线 | 国产在线黃 | 国产日韩免 | 国产涩涩视频在 | 精品香蕉伊思人在 | 国产精品欧美久 | 美日韩性| 日韩欧美精品123 | 国产在线观看福利 | 岛国成人一区二区 | 日本日韩欧美 | 日本免费-级 | 欧在线一二三四区 | 国产理论片 | 91乱伦| 国产69| 国产亚洲精爱浪 | 日韩一级中文字幕 | 国产三区视| 精品日本亚洲影视 | 欧美日韩视频网站 | 成人影院在线观看 | 中文字幕在线一 | 日本成人免费在线 | 国产好看网站 | 日本综合三级精品 | 三区四区五区高 | 日韩女人性开放视频 | 国产手机在线播放 | 91神马午夜福利 | 91性爱网 |