亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

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

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

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

背景

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

  • 輪詢,利用setTimeout定時輪詢

  • WebSocket,利用長鏈接保持與服務通訊

  • SSE,服務端推送機制

是什么

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

輪詢

輪詢就是利用setTimeout的定時器,定時向服務器發(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);

}

缺點

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

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

WebSocket

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

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

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

具體實現(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);

}

// 關閉連接

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

    });

});

缺點

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

  • 需要有完整鏈路認證,如:鑒權、登錄等

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

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

  • 服務端需要日志記錄

SSE服務端推送

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

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

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

對比WebSocket:

SSEWebSocket
單向:僅服務端能發(fā)送消息雙向:客戶端、服務端雙向發(fā)送
僅文本數(shù)據(jù)二進制、文本都可
常規(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返回內容</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()


// 監(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鏈接,

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

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

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

總結

前端實時更新需求,有多個解決方案,下面進行總結:

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

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

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

參考資料

數(shù)據(jù)不夠實時:試試長連接?


原文鏈接



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