言
哈嘍,大家好桃焕,我是澤南Zn剑肯。在之前的一篇文章寫到, 前端如何使用websocket發(fā)送消息观堂,websocket是怎么建立連接的呢让网?如果斷開了會怎樣?如何一直保持長連接呢师痕?接下來溃睹,本篇文章將會帶你了解--- WebSocket心跳機(jī)制
一、WebSocket心跳機(jī)制
前端實現(xiàn)WebSocket心跳機(jī)制的方式主要有兩種:
使用setInterval定時發(fā)送心跳包七兜。 在前端監(jiān)聽到WebSocket的onclose()事件時丸凭,重新創(chuàng)建WebSocket連接。
第一種方式會對服務(wù)器造成很大的壓力,因為即使WebSocket連接正常惜犀,也要定時發(fā)送心跳包铛碑,從而消耗服務(wù)器資源。第二種方式雖然減輕了服務(wù)器的負(fù)擔(dān)虽界,但是在重連時可能會丟失一些數(shù)據(jù)汽烦。
二、WebSocket心跳包機(jī)制
WebSocket心跳包是WebSocket協(xié)議的崩蛴活機(jī)制撇吞,用于維持長連接。有效的心跳包可以防止長時間不通訊時礁叔,WebSocket自動斷開連接牍颈。
心跳包是指在一定時間間隔內(nèi),WebSocket發(fā)送的空數(shù)據(jù)包琅关。常見的WebSocket心跳包機(jī)制如下:
客戶端定時向服務(wù)器發(fā)送心跳數(shù)據(jù)包煮岁,以保持長連接。 服務(wù)器定時向客戶端發(fā)送心跳數(shù)據(jù)包涣易,以檢測客戶端連接是否正常画机。 雙向發(fā)送心跳數(shù)據(jù)包。
三新症、WebSocket心跳機(jī)制原理
WebSocket心跳機(jī)制的原理是利用心跳包及時發(fā)送和接收數(shù)據(jù)步氏,保證WebSocket長連接不被斷開。WebSocket心跳機(jī)制的原理可以用下面的流程來說明:
客戶端建立WebSocket連接徒爹。 客戶端向服務(wù)器發(fā)送心跳數(shù)據(jù)包荚醒,服務(wù)器接收并返回一個表示接收到心跳數(shù)據(jù)包的響應(yīng)。 當(dāng)服務(wù)器沒有及時接收到客戶端發(fā)送的心跳數(shù)據(jù)包時瀑焦,服務(wù)器會發(fā)送一個關(guān)閉連接的請求腌且。 服務(wù)器定時向客戶端發(fā)送心跳數(shù)據(jù)包,客戶端接收并返回一個表示接收到心跳數(shù)據(jù)包的響應(yīng)榛瓮。 當(dāng)客戶端沒有及時接收到服務(wù)器發(fā)送的心跳數(shù)據(jù)包時铺董,客戶端會重新連接WebSocket
四、WebSocket心跳機(jī)制必要嗎
WebSocket心跳機(jī)制是必要的禀晓,它可以使 WebSocket 連接保持長連接精续,避免斷開連接的情況發(fā)生。同時粹懒,心跳機(jī)制也可以檢查WebSocket連接的狀態(tài)重付,及時處理異常情況。
五凫乖、WebSocket心跳機(jī)制作用
WebSocket心跳機(jī)制的作用主要有以下幾點:
保持WebSocket連接不被斷開确垫。
檢測WebSocket連接狀態(tài)弓颈,及時處理異常情況。
減少WebSocket連接及服務(wù)器資源的消耗删掀。
六翔冀、WebSocket重連機(jī)制
WebSocket在發(fā)送和接收數(shù)據(jù)時,可能會因為網(wǎng)絡(luò)原因披泪、服務(wù)器宕機(jī)等因素而斷開連接纤子,此時需要使用WebSocket重連機(jī)制進(jìn)行重新連接。
WebSocket重連機(jī)制可以通過以下幾種方式實現(xiàn):
前端監(jiān)聽WebSocket的onclose()事件款票,重新創(chuàng)建WebSocket連接控硼。 使用WebSocket插件或庫,例如Sockjs艾少、Stompjs等卡乾。 使用心跳機(jī)制檢測WebSocket連接狀態(tài),自動重連姆钉。 使用斷線重連插件或庫说订,例如ReconnectingWebSocket等。
七潮瓶、WebSocket的缺點和不足
WebSocket的缺點和不足主要有以下幾點:
WebSocket需要瀏覽器和服務(wù)器端都支持該協(xié)議。 WebSocket會增加服務(wù)器的負(fù)擔(dān)钙姊,不適合大規(guī)模連接的應(yīng)用場景毯辅。
八、關(guān)鍵代碼
// 開啟心跳
const start = () => {
clearTimeout(timeoutObj);
// serverTimeoutObj && clearTimeout(serverTimeoutObj);
timeoutObj = setTimeout(function () {
if (websocketRef.current?.readyState === 1) {
//連接正常
sendMessage('hello');
}
}, timeout);
};
const reset = () => {
// 重置心跳 清除時間
clearTimeout(timeoutObj);
// 重啟心跳
start();
};
ws.onopen = (event) => {
onOpenRef.current?.(event, ws);
reconnectTimesRef.current = 0;
start(); // 開啟心跳
setReadyState(ws.readyState || ReadyState.Open);
};
ws.onmessage = (message: WebSocketEventMap['message']) => {
const { data } = message;
if (data === '收到煞额,hello') {
reset();
return;
}
if (JSON.parse(data).status === 408) {
reconnect();
return;
}
onMessageRef.current?.(message, ws);
setLatestMessage(message);
};
const connect = () => {
reconnectTimesRef.current = 0;
connectWs();
};
主要思路:在建立長連接的時候開啟心跳思恐,通過和服務(wù)端發(fā)送信息,得到服務(wù)端給返回的信息膊毁,然后重置心跳胀莹,清楚時間,再重新開啟心跳婚温。如果網(wǎng)絡(luò)斷開的話描焰,會執(zhí)行方法,重新連接栅螟。
作者:一只小錦李_
鏈接:
https://juejin.cn/post/7290005438153867283