WebSocket斷線重連

Websites發表於2018-09-10

WebSocket斷線重連 即時通訊 心跳重連
廢話不多說,直接上程式碼.

$scope.timeout = 10800,//3分鐘發一次心跳
$scope.timeoutObj = null,
$scope.serverTimeoutObj = null,
$scope.init = function() {
    $scope.lockReconnect = false,
    $scope.wsUrl = "wss://xxx:8888";
    // 監聽視窗關閉事件,當視窗關閉時,主動去關閉websocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常。
    window.onbeforeunload = function() {
        ws.close();
    }
    //建立WebSocket物件
    $scope.createWebSocket = function() {
        try {
            if(window.WebSocket || window.MozWebSocket) {
                ws = new WebSocket($scope.wsUrl);
            }
            $scope.initEventHandle();
        } catch(e) {
            $scope.reconnectWebSocket($scope.wsUrl);
        }
    },
    $scope.initEventHandle = function() {
        /*** 連線建立時觸發  */
        ws.onopen = function(e) {
            //傳送登入資訊
            msg = new Object();
            ws.send('xxx');

            $scope.heartCheckWebSocket(); //心跳檢測重置
        };
        ws.onmessage = function(e) {
            $scope.heartCheckWebSocket(); //如果獲取到訊息,心跳檢測重置
            //拿到任何訊息都說明當前連線是正常的

            $scope.handMsg(e.data);
        };
        ws.onclose = function(e) {
            $scope.reconnectWebSocket($scope.wsUrl);
            //console.log("伺服器拒絕了連線. 請檢查伺服器是否啟動");
        };
        ws.onerror = function(e) {
            $scope.reconnectWebSocket($scope.wsUrl);
            //console.log("連線已斷開,請重新整理頁面重新登入。");
        };
    },
    //處理訊息
    $scope.handMsg = function(eventData) {
        if(!eventData) return;

        if(eventData == "close") {
            $scope.reconnectWebSocket($scope.wsUrl);
            //這裡要注意onclose的第一個引數必須是1000或者3000—4999
            //console.log("伺服器通知關閉");
        } else {
            //這裡收到後端返回一個心跳訊息,如果data返回空,則說明連線正常,到此停止處理
            //這裡是你要寫的邏輯程式碼
        }
    },
    //重連
    $scope.reconnectWebSocket = function() {
        if($scope.lockReconnect) return;
        $scope.lockReconnect = true;
        setTimeout(function() {
            $scope.createWebSocket(wsUrl);
            $scope.lockReconnect = false;
        }, 2000);
    },
    //心跳檢測
    $scope.heartCheckWebSocket = function() {
        //重置
        $timeout.cancel($scope.timeoutObj);
        $timeout.cancel($scope.serverTimeoutObj);
        //開啟
        $scope.timeoutObj = $timeout(function() {
            //這裡傳送一個心跳,後端收到後,返回一個心跳訊息,
            //onmessage拿到返回的心跳就說明連線正常
            //傳送登入資訊
            msg = new Object();
            ws.send('xxx');
            $scope.serverTimeoutObj = $timeout(function() {
                //如果超過一定時間還沒重置,說明後端主動斷開了
                //如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
                ws.close();
            }, $scope.timeout);
        }, $scope.timeout);
    }
}

相關文章