161114、websocket實現心跳重連


心跳重連緣由

在使用websocket過程中,可能會出現網絡斷開的情況,比如信號不好,或者網絡臨時性關閉,這時候websocket的連接已經斷開,

而瀏覽器不會執行websocket 的 onclose方法,我們無法知道是否斷開連接,也就無法進行重連操作。

如果當前發送websocket數據到后端,一旦請求超時,onclose便會執行,這時候便可進行綁定好的重連操作。

因此websocket心跳重連就應運而生。

 

如何實現

在websocket實例化的時候,我們會綁定一些事件:

復制代碼
var ws = new WebSocket(url);
ws.onclose = function () {
    //something
};
ws.onerror = function () {
    //something
};
        
ws.onopen = function () {
   //something
};
ws.onmessage = function (event) {
   //something
}
復制代碼

如果希望websocket連接一直保持,我們會在close或者error上綁定重新連接方法。

復制代碼
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
    
復制代碼

這樣一般正常情況下失去連接時,觸發onclose方法,我們就能執行重連了。

 

那么針對斷網的情況的心跳重連,怎么實現呢。

簡單的實現:

復制代碼
var heartCheck = {
    timeout: 60000,//60ms
    timeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
     this.start(); }, start: function(){ this.timeoutObj = setTimeout(function(){ ws.send("HeartBeat", "beat"); }, this.timeout) } } ws.onopen = function () { heartCheck.start(); };
ws.onmessage = function (event) {
    heartCheck.reset();
}
復制代碼

如上代碼,heartCheck 的 reset和start方法主要用來控制心跳的定時。

當onopen也就是連接上時,我們便開始start計時,如果在定時時間范圍內,onmessage獲取到了服務器的消息,我們就重置倒計時,

所以在距離上次從服務器獲取到消息,閑置60秒之后我們才會心跳檢測,這個檢測時間可以自己根據自身情況設定。

當心跳檢測send執行之后,如果當前websocket是斷開狀態,發送超時之后,onclose方法便會被執行,重連也執行了。

如此一來,我們的心跳檢測就實現了。

 

后來,我本想測試websocket超時時間,又發現了一些新的問題

1. 在chrome中,如果心跳檢測 也就是websocket實例執行send之后,15秒內沒發送到另一接收端,onclose便會執行。那么超時時間是15秒。

2. 我又打開了Firefox ,Firefox在斷網7秒之后,直接執行onclose。說明在Firefox中不需要心跳檢測便能自動onclose。

3.  同一代碼, reconnect方法 在chrome 執行了一次,Firefox執行了兩次。當然我們在幾處地方(代碼邏輯處和websocket事件處)綁定了reconnect(),

所以保險起見,我們還是給reconnect()方法加上一個鎖,保證只執行一次

 

目前來看不同的瀏覽器,有不同的機制,無論瀏覽器websocket自身會不會在斷網情況下執行onclose,加上心跳重連后,已經能保證onclose的正常觸發。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM