天天看點

Websocket實作斷網重連

Websocket實作斷網重連

代碼如下:

定義的變量如下:

var lockReconnect = false;//避免重複連接配接
var wsUrl = "ws://localhost:8080/websocket/111";		// websocket連結
var ws;// websocket對象
           

首先判斷是否支援websocket

if ("WebSocket" in window) {
 ....
 }else{
 	 alert("您的浏覽器不支援websocket 請更換浏覽器後重試!");
 }
           

建立一個websocket對象

function createWebSocket(){
            try {
                ws = new WebSocket(wsUrl);
                websocketInit();//對websocket對象進行初始化
            } catch (e) {
                console.log('建立異常 執行重連。。');
                websocketReconnect(wsUrl);//調用重連方法
            }
        }

        createWebSocket();			// 建立websocket
           

建立了一個websocketInit方法 對websocket進行初始化

function websocketInit () {
            // 建立 websocket 連接配接成功觸發事件
            ws.onopen = function (evt) {
                onOpen(evt);//連接配接成功後執行的方法
            };
            // 斷開 web socket 連接配接成功觸發事件
            ws.onclose = function (evt) {			
                websocketReconnect(wsUrl);
                onClose(evt);//斷開連接配接成功後執行的方法
            };
            // 接收服務端資料時觸發事件
            ws.onmessage = function (evt) {
                onMessage(evt);// 接收服務端資料時執行的方法
            };
            // 通信發生錯誤時觸發
            ws.onerror = function (evt) {
                websocketReconnect(wsUrl);
                onError(evt);// 通信發生錯誤時執行的方法
            };
        };
           

執行的方法

連接配接以後 重置心跳檢測

接收資料後

如果是正常的傳回心跳資料

再執行心跳檢測

每次執行心跳檢測 向伺服器發送一條資料 伺服器就會傳回一條資料(隻要在設定的延時内) 用戶端再接收到資料 就會重新調用心跳檢測方法

不過拿到任何消息都說明目前連接配接是正常的

function onOpen(evt) {
            console.log("建立連接配接");
            //心跳檢測重置
            heartCheck.start();
        }

        function onClose(evt) {
            console.log("連接配接已關閉...");
        }

        function onMessage(evt) {
            console.log('接收消息: ' + evt.data);
            var data = JSON.parse(evt.data);
            console.log(data);
            console.log(data.heart);
            if (data.hasOwnProperty("heart")) {// 存在key為heart
                    if (data.heart=="live"){// 心跳正常 再次執行
                        heartCheck.start();
                       	console.log('心跳正常 再次執行心跳檢測方法!');
                    }
                    return;
            }
        }
        
        function onError(evt) {
            console.log('通信錯誤:' + evt.data);
        }

           

執行斷網重連的方法

設定延遲一直調用 createWebSocket方法連接配接

function websocketReconnect(url) {
            if (lockReconnect) {       // 是否已經執行重連
                return;
            };
            lockReconnect = true;
            //沒連接配接上會一直重連,設定延遲避免請求過多
            tt && clearTimeout(tt);
            var tt = setTimeout(function () {
                createWebSocket(url);
                lockReconnect = false;
            }, 5000);
        }
           

心跳檢測的方法

每30s執行一次心跳檢測

每次執行心跳檢測 向伺服器發送一條資料 伺服器就會傳回一條資料(隻要在設定的延時(30秒)内) 用戶端再接收到資料 就會重新調用心跳檢測方法

如果發生異常 就會調用ws.close();方法 close方法就會一直重複的調用重連方法 直到再次連接配接上伺服器 完成斷網重連!

//心跳檢測
        var heartCheck = {
            timeout: 30000,
            timeoutObj: null,
            serverTimeoutObj: null,
            start: function () {
                console.log('開始心跳檢測');
                var self = this;
                this.timeoutObj && clearTimeout(this.timeoutObj);
                this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
                this.timeoutObj = setTimeout(function () {
                    //發送測試資訊,後端收到後,傳回一個消息,
                    ws.send("1");
                    self.serverTimeoutObj = setTimeout(function () {
                        ws.close();
                    }, self.timeout);
                }, this.timeout)
            }
        }
           

完整的代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    var lockReconnect = false;//避免重複連接配接
    var wsUrl = "ws://localhost:8080/websocket/111";		// websocket連結
    var ws;
    if ("WebSocket" in window) {
        function createWebSocket(){
            try {
                ws = new WebSocket(wsUrl);
                websocketInit();
            } catch (e) {
                console.log('catch');
                websocketReconnect(wsUrl);
            }
        }

        createWebSocket();			// 建立websocket

        function websocketInit () {
            // 建立 web socket 連接配接成功觸發事件
            ws.onopen = function (evt) {
                onOpen(evt);
            };
            // 斷開 web socket 連接配接成功觸發事件
            ws.onclose = function (evt) {			
                websocketReconnect(wsUrl);
                onClose(evt);
            };
            // 接收服務端資料時觸發事件
            ws.onmessage = function (evt) {
                onMessage(evt);
            };
            // 通信發生錯誤時觸發
            ws.onerror = function (evt) {
                websocketReconnect(wsUrl);
                onError(evt);
            };
        };

        function onOpen(evt) {
            console.log("建立連接配接");
            //心跳檢測重置
            heartCheck.start();
        }

        function onClose(evt) {
            console.log("連接配接已關閉...");
        }

       function onMessage(evt) {
            console.log('接收消息: ' + evt.data);
            var data = JSON.parse(evt.data);
            console.log(data);
            console.log(data.heart);
            if (data.hasOwnProperty("heart")) {// 存在key為heart
                    if (data.heart=="live"){// 心跳正常 再次執行
                        heartCheck.start();
                       	console.log('心跳正常 再次執行心跳檢測方法!');
                    }
                    return;
            }
        }
        
        function onError(evt) {
            console.log('通信錯誤:' + evt.data);
        }


        function websocketReconnect(url) {
            if (lockReconnect) {       // 是否已經執行重連
                return;
            };
            lockReconnect = true;
            //沒連接配接上會一直重連,設定延遲避免請求過多
            tt && clearTimeout(tt);
            var tt = setTimeout(function () {
                createWebSocket(url);
                lockReconnect = false;
            }, 5000);
        }

        //心跳檢測
        var heartCheck = {
            timeout: 30000,
            timeoutObj: null,
            serverTimeoutObj: null,
            start: function () {
                console.log('執行心跳檢測');
                var self = this;
                this.timeoutObj && clearTimeout(this.timeoutObj);
                this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
                this.timeoutObj = setTimeout(function () {
                    //發送測試資訊,後端收到後,傳回一個消息,
                    ws.send("heart");
                    self.serverTimeoutObj = setTimeout(function () {
                        ws.close();
                    }, self.timeout);
                }, this.timeout)
            }
        }

       
    }else{
        alert("您的浏覽器不支援websocket 請更換浏覽器後重試!");
    } 

        </script>
</body>
</html>
           

測試圖

Websocket實作斷網重連