var ws;//websocket實例 var heartCheck; var lockReconnect = false;//避免重復(fù)連接 var wsUrl = "ws://116.62.207.100:8080/websocket"; function createWebSocket(url) { try { ws = new WebSocket(url); initEventHandle(); } catch (e) { reconnect(url); } } function initEventHandle() { ws.onclose = function () { console.log("webscoket關(guān)閉狀態(tài)即將重連...") reconnect(wsUrl); }; ws.onerror = function () { console.log("webscoket異常狀態(tài)即將重連...") reconnect(wsUrl); }; ws.onopen = function () { console.log("webscoket已經(jīng)鏈接 心跳檢測重置中...") //心跳檢測重置 heartCheck.reset().start(); }; ws.onmessage = function (event) { console.log("【收到】:" + event.data); //如果獲取到消息,心跳檢測重置 //拿到任何消息都說明當(dāng)前連接是正常的 heartCheck.reset().start(); } } function reconnect(url) { if(lockReconnect) return; lockReconnect = true; //沒連接上會一直重連,設(shè)置延遲避免請求過多 setTimeout(function () { createWebSocket(url); lockReconnect = false; }, 2000); } //心跳檢測 heartCheck = { timeout: 90000,//90秒 timeoutObj: null, serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; //這里發(fā)送一個心跳,后端收到后,返回一個心跳消息, //onmessage拿到返回的心跳就說明連接正常 send("HeadBeat"); this.timeoutObj = setTimeout(function(){ console.log("【走到這一步的原因很簡單,因為你沒有收到心跳消息,那么N秒后將自動關(guān)閉重連】") self.serverTimeoutObj = setTimeout(function(){//如果超過一定時間還沒重置,說明后端主動斷開了 ws.close();//如果onclose會執(zhí)行reconnect,我們執(zhí)行ws.close()就行了.如果直接執(zhí)行reconnect 會觸發(fā)onclose導(dǎo)致重連兩次 }, self.timeout) }, this.timeout) } } createWebSocket(wsUrl); //WebSocket發(fā)送請求 function send(message) { if (!window.WebSocket) { return; } if (ws.readyState == WebSocket.OPEN) { console.log('【發(fā)送】:'+JSON.stringify(message)) ws.send(JSON.stringify(message)); } else { layui.use('layer', function(){ var layer = layui.layer; layer.msg('您還未連接上服務(wù)器,請刷新頁面重試!',{icon: 0}); }) } } |
|