国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

為什么WebSocket需要前端心跳檢測,有沒有原生的檢測機(jī)制?

這篇具有很好參考價(jià)值的文章主要介紹了為什么WebSocket需要前端心跳檢測,有沒有原生的檢測機(jī)制?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文代碼 github、gitee、npm

在web應(yīng)用中,WebSocket是很常用的技術(shù)。通過瀏覽器的WebSocket構(gòu)造函數(shù)就可以建立一個WebSocket連接。但當(dāng)需要應(yīng)用在具體項(xiàng)目中時,幾乎都會進(jìn)行心跳檢測。

設(shè)置心跳檢測,一是讓通訊雙方確認(rèn)對方依舊活躍,二是瀏覽器端及時檢測當(dāng)前網(wǎng)絡(luò)線路可用性,保證消息推送的及時性。

你可能會想,WebSocket那么簡陋的嗎,居然不能自己判斷連接狀態(tài)?在了解前先來回顧一下計(jì)算機(jī)網(wǎng)絡(luò)知識。

相關(guān)的網(wǎng)絡(luò)知識

TCP/IP協(xié)議族四層結(jié)構(gòu):

  • 應(yīng)用層:決定了向用戶提供應(yīng)用服務(wù)時通信的活動。HTTP、FTP、WebSocket都是應(yīng)用層協(xié)議

  • (TCP)傳輸控制層:控制網(wǎng)絡(luò)中兩臺主機(jī)的數(shù)據(jù)傳輸:將應(yīng)用層數(shù)據(jù)(有必要時對應(yīng)用層報(bào)文分段,例如一個完整的HTTP報(bào)文進(jìn)行分段)發(fā)送到目標(biāo)主機(jī)的特定端口的應(yīng)用程序。給每個數(shù)據(jù)標(biāo)記源端口、目標(biāo)端口、分段后的序號。

  • (IP)網(wǎng)絡(luò)層:將IP地址映射為目標(biāo)主機(jī)的MAC地址,然后將TCP數(shù)據(jù)包(有必要時對數(shù)據(jù)分片)加入源IP、目標(biāo)IP等信息后經(jīng)過鏈路層扔到網(wǎng)絡(luò)上讓其找到目標(biāo)主機(jī)。

  • 鏈路層:為IP網(wǎng)絡(luò)層進(jìn)行發(fā)送、接收數(shù)據(jù)報(bào)。將二進(jìn)制數(shù)據(jù)包與在網(wǎng)線傳輸?shù)木W(wǎng)絡(luò)電信號進(jìn)行相互轉(zhuǎn)換。

TCP是可靠的連接,握手建立連接后,發(fā)送方每發(fā)送一個TCP報(bào)文(對應(yīng)用層報(bào)文分段后形成多個TCP報(bào)文),都會期望對方在指定時間里返回已收到的確認(rèn)消息,如果超時沒有回應(yīng),會重復(fù)發(fā)送,確保所有TCP報(bào)文可以到達(dá)對方,被對方按順序拼接成應(yīng)用層需要的完整報(bào)文。

WebSocket協(xié)議支持在TCP 上層引入 TLS 層,建立加密通信。

WebSocket與HTTP的異同:

  • WebSocket和HTTP一樣是應(yīng)用層協(xié)議,在傳輸層使用了TCP協(xié)議,都是可靠的連接。WebSocket在建立連接時,可以使用已有的HTTP的GET請求進(jìn)行握手:客戶端在請求頭中將WebSocket協(xié)議版本等信息發(fā)生到服務(wù)器,服務(wù)器同意的話,會響應(yīng)一個101的狀態(tài)碼。就是說一次HTTP請求和響應(yīng),即可輕松轉(zhuǎn)換協(xié)議到WebSocket。

  • WebSocket可以互相發(fā)起請求。當(dāng)有新消息時,服務(wù)器主動通知客戶端,無需客戶端主動向服務(wù)器詢問??蛻舳艘部梢韵蚝蠖税l(fā)送消息。而HTTP中請求只能由客戶端發(fā)起。

  • WebSocket是HTML5的內(nèi)容,HTTP則是超文本傳輸協(xié)議,比HTML5誕生更早。

  • 在應(yīng)用層,WebSocket的每個報(bào)文(在WebSocket中叫數(shù)據(jù)幀)會比HTTP報(bào)文(必須包含請求行、請求頭、請求數(shù)據(jù))更輕量。

    • WebSocket每個數(shù)據(jù)幀只有固定的頭信息,不會有cookie等或者自定義的頭信息。建立通訊后是一對一的,不需要攜帶驗(yàn)證信息。使用HTTP握手時,的握手請求會自動攜帶cookie。
    • WebSocket在應(yīng)用層就會將大的數(shù)據(jù)進(jìn)行分拆,而HTTP不會。

WebSocket與與WebRTC的異同:

  • WebRTC是一種通訊技術(shù),由谷歌發(fā)起,被廣大瀏覽器實(shí)現(xiàn)。用來建立瀏覽器和瀏覽器間的通訊,如視頻通話等。而WebSocket是一種經(jīng)過抽象的協(xié)議,可以實(shí)現(xiàn)為通訊技術(shù)。用來建立瀏覽器和服務(wù)器間的通訊。

協(xié)議中的心跳檢測機(jī)制

從網(wǎng)上檢索的答案,WebSocket大概有兩種從協(xié)議角度出發(fā)的,檢測對方存活的方式:

  1. WebSocket只是一個應(yīng)用層協(xié)議規(guī)范,其傳輸層是TCP,而TCP為長連接提供KeepAlive機(jī)制,可以定時發(fā)送心跳報(bào)文確認(rèn)對方的存活,但一般是服務(wù)器端使用。因?yàn)槭荰CP傳輸控制層的機(jī)制,具體的實(shí)現(xiàn)要看操作系統(tǒng),也就是說應(yīng)用層接收到的連接狀態(tài)是操作系統(tǒng)通知的,不同操作系統(tǒng)的資源調(diào)度是不一樣的,例如何時發(fā)送探測報(bào)文(不包含有效數(shù)據(jù)的TCP報(bào)文)檢測對方的存活,頻率是多久,在不同的系統(tǒng)配置下存在差異??赡苁?小時進(jìn)行一次心跳檢測,或許更短。如果連續(xù)沒有收到對方的應(yīng)答包,才會通知應(yīng)用層已經(jīng)斷開連接。這就帶來了不確定性。同時也意味著其它依賴該機(jī)制的應(yīng)用層協(xié)議也會被影響。也就是說要利用這個過程進(jìn)行檢測,客戶端要修改操作系統(tǒng)的TCP配置才行,在瀏覽器環(huán)境顯然不行。參考1、參考2

  2. WebSocket協(xié)議也有自身的?;顧C(jī)制,但需要通訊雙方的實(shí)現(xiàn)。WebSocket通訊的數(shù)據(jù)幀會有一個4位的OPCODE,標(biāo)記當(dāng)前傳輸?shù)臄?shù)據(jù)幀類型,例如:0x8表示關(guān)閉幀、0x9表示ping幀、0xA表示pong幀、0x1普通文本數(shù)據(jù)幀等。www.rfc-editor.org

    • 關(guān)閉數(shù)據(jù)幀,在任意一方要關(guān)閉通道時,發(fā)送給對方。例如瀏覽器的WebSocket實(shí)例調(diào)用close時,就會發(fā)送一個OPCODE為連接關(guān)閉的數(shù)據(jù)幀給服務(wù)器端,服務(wù)器端接收到后同樣需要返回一個關(guān)閉數(shù)據(jù)幀,然后關(guān)閉底層的TCP連接。
    • ping數(shù)據(jù)幀,用于發(fā)送方詢問對方是否存活,也就是心跳檢測包。目前只有后端可以控制ping數(shù)據(jù)幀的發(fā)送。但瀏覽器端的WebSocket實(shí)例上沒有對應(yīng)的api可用。
    • pong數(shù)據(jù)幀,當(dāng)WebSocket通訊一方接收到對方發(fā)送的ping數(shù)據(jù)幀后,需要及時回復(fù)一個內(nèi)容一致,且OPCODE標(biāo)記為pong的數(shù)據(jù)幀,告訴對方我還在。但目前回復(fù)pong是瀏覽器的自動行為,意味著不同瀏覽器會有差異。而且在js中沒有相關(guān)api可以控制。

綜上所述,探測對方存活的方式都是服務(wù)器主動進(jìn)行心跳檢測。瀏覽器并沒有提供相關(guān)能力。為了能夠在瀏覽器端實(shí)時探測后端的存活,或者說連接依舊可用,只能自己實(shí)現(xiàn)心跳檢測。

瀏覽器端心跳檢測的必要性

首先我們先了解一下,目前的瀏覽器端的WebSocket何時會自動關(guān)閉WebSocket,并觸發(fā)close事件呢?

  • 握手時的WebSocket地址不可用。
  • 其它未知錯誤。
  • 正常連接狀態(tài)下,接收到服務(wù)器端的關(guān)閉幀就會觸發(fā)關(guān)閉回調(diào)。

也就是說建立正常連接后,中途瀏覽器端斷網(wǎng)了,或者服務(wù)器沒有發(fā)送關(guān)閉幀就關(guān)了連接,總之就是在連接無法再使用的情況下,瀏覽器沒有接收到關(guān)閉幀,瀏覽器則會長時間保持連接狀態(tài)。此時業(yè)務(wù)代碼不去主動探測的話,是無法感知的。

另外通訊雙方保持連接意味著需要長時間占用對方的資源。對于服務(wù)器端來說資源是非常寶貴的。長時間不活躍的連接,可能會被服務(wù)器應(yīng)用層框架"優(yōu)化"釋放掉。

前端實(shí)現(xiàn)心跳檢測

實(shí)例化一個WebSocket:

function connectWS() {
    const WS = new WebSocket("ws://127.0.0.1:7070/ws/?name=greaclar");
    // WebSocket實(shí)例上的事件

    // 當(dāng)連接成功打開
    WS.addEventListener('open', () => {
        console.log('ws連接成功');
    });
    // 監(jiān)聽后端的推送消息
    WS.addEventListener('message', (event) => {
        console.log('ws收到消息', event.data);
    });
    // 監(jiān)聽后端的關(guān)閉消息,如果發(fā)送意外錯誤,這里也會觸發(fā)
    WS.addEventListener('close', () => {
        console.log('ws連接關(guān)閉');
    });
    // 監(jiān)聽WS的意外錯誤消息
    WS.addEventListener('error', (error) => {
        console.log('ws出錯', error);
    });
    return WS;
}

let WS = connectWS();

心跳檢測需要用到的實(shí)例方法:

// 發(fā)送消息,用來發(fā)送心跳包
WS.send('hello'); 
// 關(guān)閉連接,當(dāng)發(fā)送心跳包不響應(yīng),需要重連時,最好先關(guān)閉
WS.close();

定義發(fā)送心跳包的邏輯:

準(zhǔn)備

  • 申請一個變量heartbeatStatus,記錄當(dāng)前心跳檢測狀態(tài),有三個狀態(tài):等待中,已收到應(yīng)答、超時。
  • 監(jiān)聽WS實(shí)例的message事件,監(jiān)聽到就將heartbeatStatus改為:已收到應(yīng)答。
  • 監(jiān)聽WS實(shí)例的open事件,打開后啟動心跳檢測。

檢測

  • 啟動一個定時器A。

  • 定時器A執(zhí)行,1.修改當(dāng)前狀態(tài)heartbeatStatus為等待中;2.發(fā)送心跳包;3.啟動一個定時器B。

    • 發(fā)送心跳包后,后端需要立刻推送一個內(nèi)容一樣的心跳應(yīng)答包給前端,觸發(fā)前端WS實(shí)例的message事件,繼而將heartbeatStatus改為已收到應(yīng)答。
  • 定時器B執(zhí)行,檢測當(dāng)前heartbeatStatus狀態(tài):

    • 如果是已收到應(yīng)答,證明定時器A執(zhí)行后,服務(wù)器可以及時響應(yīng)數(shù)據(jù)。繼續(xù)啟動定時器A,然后不斷循環(huán)。

    • 如果是等待中,證明連接出現(xiàn)問題了,走關(guān)閉或者檢測流程。

let WS = connectWS();
let heartbeatStatus = 'waiting';

WS.addEventListener('open', () => {
    // 啟動成功后開啟心跳檢測
    startHeartbeat()
})

WS.addEventListener('message', (event) => {
    const { data } = event;
    console.log('心跳應(yīng)答了,要把狀態(tài)改為已收到應(yīng)答', data);
    if (data === '"heartbeat"') {
        heartbeatStatus = 'received';
    }
})

function startHeartbeat() {
    setTimeout(() => {
        // 將狀態(tài)改為等待應(yīng)答,并發(fā)送心跳包
        heartbeatStatus = 'waiting';
        WS.send('heartbeat');
        // 啟動定時任務(wù)來檢測剛才服務(wù)器有沒有應(yīng)答
        waitHeartbeat();
    }, 1500)
}

function waitHeartbeat() {
    setTimeout(() => {
        console.log('檢測服務(wù)器有沒有應(yīng)答過心跳包,當(dāng)前狀態(tài)', heartbeatStatus);
        if (heartbeatStatus === 'waiting') {
            // 心跳應(yīng)答超時
            WS.close();
        } else {
            // 啟動下一輪心跳檢測
            startHeartbeat();
        }
    }, 1500)
}

優(yōu)化心跳檢測

心跳檢測異常,但close事件沒有觸發(fā),大概率是雙方之間的網(wǎng)絡(luò)線路不佳,如果立馬進(jìn)行重連,會擠兌更多的網(wǎng)絡(luò)資源,重連的失敗概率更大,也可能阻塞用戶的其它操作。

但也不排除確實(shí)是連接的問題,如服務(wù)器宕機(jī)、意外重啟,同時沒有告知瀏覽器需要把舊連接關(guān)閉。

所以一發(fā)生心跳不應(yīng)答,個人推薦的做法是,發(fā)生延遲后,提醒用戶網(wǎng)絡(luò)異常正在修復(fù)中,讓用戶有個心理準(zhǔn)備。然后多發(fā)一兩個心跳包,連續(xù)不應(yīng)答再提示用戶掉線了,是否重連。如果中途正常了,就不需要重連,用戶體驗(yàn)更好,對服務(wù)器的壓力也更小。

// 以上代碼需要修改的地方

// 添加一個變量來記錄連續(xù)不應(yīng)答次數(shù)
let retryCount = 0WS.addEventListener('message', (event) => {
    const { data } = event;
    console.log('心跳應(yīng)答了,要把狀態(tài)改為已收到應(yīng)答', data);
    if (data === '"heartbeat"') {
        // 復(fù)位連續(xù)不應(yīng)答次數(shù)
        retryCount = 0;
        heartbeatStatus = 'received';
    }
})

// 在等待應(yīng)答的函數(shù)中添加重試的邏輯
function waitHeartbeat() {
    setTimeout(() => {
        // 心跳應(yīng)答正常,啟動下一輪心跳檢測
        if (heartbeatStatus === 'received') {
            return startHeartbeat();
        }
        // 更新超時次數(shù)
        retryCount ++;
        // 心跳應(yīng)答超時,但沒有連續(xù)超過三次
        if (retryCount < 3) {
            alert('ws線路異常,正在檢測中。')
            return startHeartbeat();
        }
        
        // 超時次數(shù)超過三次
        WS.close();
    }, 1500)
}

最后,為了方便大家共同進(jìn)步,本文已經(jīng)把相關(guān)的邏輯封裝為一個類,并且在npm中可下載玩一下,也已經(jīng)開源到github上。文章來源地址http://www.zghlxwxcb.cn/news/detail-780375.html

到了這里,關(guān)于為什么WebSocket需要前端心跳檢測,有沒有原生的檢測機(jī)制?的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 為什么需要超時控制

    本文將介紹為什么需要超時控制,然后詳細(xì)介紹Go語言中實(shí)現(xiàn)超時控制的方法。其中,我們將討論 time 包和 context 包實(shí)現(xiàn)超時控制的具體方式,并說明兩者的適用場景,以便在程序中以更合適的方式來實(shí)現(xiàn)超時控制,提高程序的穩(wěn)定性和可靠性。 超時控制可以幫助我們避免程

    2024年02月03日
    瀏覽(26)
  • 為什么需要數(shù)據(jù)倉庫

    為什么不在OLTP環(huán)境下分析?? OLTP環(huán)境也會存儲歷史數(shù)據(jù),但這些歷史數(shù)據(jù)并不是業(yè)務(wù)運(yùn)行所需的,這些歷史數(shù)據(jù)需要經(jīng)常歸檔到數(shù)據(jù)倉庫,并且在OLTP數(shù)據(jù)庫中刪除。 相比之下,事務(wù)環(huán)境適用于連續(xù)處理事務(wù),通常應(yīng)用于訂單錄入以及財(cái)務(wù)和零售事務(wù)。它們并不依賴歷史數(shù)據(jù)

    2024年01月25日
    瀏覽(31)
  • 為什么需要單元測試?

    為什么需要單元測試?

    為什么需要單元測試? 從產(chǎn)品角度而言,常規(guī)的功能測試、系統(tǒng)測試都是站在產(chǎn)品局部或全局功能進(jìn)行測試,能夠很好地與用戶的需要相結(jié)合,但是缺乏了對產(chǎn)品研發(fā)細(xì)節(jié)(特別是代碼細(xì)節(jié)的理解)。 從測試人員角度而言,功能測試和系統(tǒng)測試以及其他性能測試等等對測試

    2024年02月12日
    瀏覽(34)
  • uniapp前端+python后端=微信小程序支付到底怎么開發(fā)???國內(nèi)的資料為什么沒一篇能講清楚,簡簡單單的只需要3步就可以了-V2版本

    uniapp前端+python后端=微信小程序支付到底怎么開發(fā)???國內(nèi)的資料為什么沒一篇能講清楚,簡簡單單的只需要3步就可以了-V2版本

    真的,在接到這個任務(wù)的時候,本以為很簡單,不就是普通的瀏覽器復(fù)制粘貼,最不濟(jì)找下gpt給生成一下,但是到實(shí)際開發(fā)就不同了,不是后端出問題就是前端,搜資料,上百度上google,基本每一個人講的都不一樣,不是這問題就是那問題,特別是微信官方,自己接口的邏輯

    2024年01月22日
    瀏覽(30)
  • 為什么自動駕駛需要5G?

    為什么自動駕駛需要5G?

    什么叫自動駕駛? 自動駕駛分為6個等級: Level 0: 人工駕駛,無駕駛輔助系統(tǒng),僅提醒。 Level 1: 輔助人工駕駛,可實(shí)現(xiàn)單一的車速或轉(zhuǎn)向控制自動化,仍由人工駕駛(如定速巡航、ACC)。 Level 2: 部分自動駕駛,可實(shí)現(xiàn)車速和轉(zhuǎn)向控制自動化,駕駛員必須始終保持監(jiān)控(

    2024年02月08日
    瀏覽(35)
  • 為什么需要對相機(jī)標(biāo)定?

    為什么需要對相機(jī)標(biāo)定?

    以下內(nèi)容來自系統(tǒng)教程如何搞定單目/魚眼/雙目/陣列 相機(jī)標(biāo)定? 點(diǎn)擊領(lǐng)取相機(jī)標(biāo)定資料和代碼 為什么需要對相機(jī)標(biāo)定? 我們所處的世界是三維的,而相機(jī)拍攝的照片卻是二維的,丟失了其中距離/深度的信息。從數(shù)學(xué)上可以簡單理解為,相機(jī)本身類似一個映射函數(shù),其將輸

    2024年02月06日
    瀏覽(25)
  • 爬蟲時為什么需要代理?

    我們都知道爬蟲時是需要代理地址介入的。使用代理可以隱藏你的真實(shí)IP地址,防止被網(wǎng)站封禁或限制訪問。此外,代理還可以幫助你繞過地理限制,訪問被封鎖的網(wǎng)站或服務(wù)。但是請注意,使用代理也可能會帶來一些風(fēng)險(xiǎn),例如代理服務(wù)器可能會記錄你的訪問數(shù)據(jù),或者代

    2024年02月06日
    瀏覽(25)
  • 爬蟲為什么需要ip

    爬蟲為什么需要ip

    爬蟲需要使用爬蟲ip主要是為了解決以下問題: 1、反爬蟲機(jī)制:許多網(wǎng)站會設(shè)置反爬蟲機(jī)制來防止爬蟲程序的訪問,例如限制IP地址的訪問頻率、檢測訪問來源等。使用爬蟲ip可以繞過這些限制,使得爬蟲程序更難被檢測到。 2、訪問限制:有些網(wǎng)站可能會對某些地區(qū)的IP地址

    2024年02月02日
    瀏覽(27)
  • 為什么CPU需要時鐘

    為什么CPU需要時鐘

    為什么CPU需要時鐘這樣一個概念? 什么是時鐘脈沖,CPU為什么需要時鐘,時鐘信號是怎么產(chǎn)生的? 上面這個圖的方波就是一個脈沖,類比于人類的脈搏跳動。一個脈沖稱之為CPU的一個 時鐘信號 ,或者 時鐘脈沖 。一個脈沖周期就叫CPU時鐘周期,一個時鐘周期內(nèi)時鐘信號震蕩一

    2023年04月11日
    瀏覽(21)
  • 什么是分庫分表?為什么需要分表?什么時候分庫分表

    什么是分庫分表?為什么需要分表?什么時候分庫分表

    不急于上手實(shí)戰(zhàn)? ShardingSphere ?框架,先來復(fù)習(xí)下分庫分表的基礎(chǔ)概念,技術(shù)名詞大多晦澀難懂,不要死記硬背理解最重要,當(dāng)你捅破那層窗戶紙,發(fā)現(xiàn)其實(shí)它也就那么回事。 分庫分表是在海量數(shù)據(jù)下,由于單庫、表數(shù)據(jù)量過大,導(dǎo)致數(shù)據(jù)庫性能持續(xù)下降的問題,演變出的技

    2023年04月26日
    瀏覽(52)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包