WebSocket隔一段時間會斷開,增加心跳機制防止自動斷開連接


系統發現websocket每隔1分鍾自動斷開連接,搜了很多博客都說設置一下nginx的proxy_read_timeout
但是這個時間過長會影響服務器性能,采取心跳包的方式每隔1分鍾客戶端自動發送ping消息給服務端,服務端需要返回pong。即可解決問題。

心跳機制發送的信息在后台判斷不發送至客戶端即可。

    var webSocket = null;

    function send_msg() {
        var t = "";
        if (webSocket != null) {
            var input_msg = document.getElementById("input_msg").value.trim();
            if (input_msg == "") {
                return;
            }
            webSocket.send(input_msg);
            // 清除input框里的信息
            document.getElementById("input_msg").value = "";
            // var msg_board = document.getElementsByClassName("msg_board")[0];
            // var received_msg = input_msg;
            // var old_msg = msg_board.innerHTML;
            // msg_board.innerHTML = old_msg + received_msg + "<br>";
            // // 讓滾動塊往下移動
            // msg_board.scrollTop = msg_board.scrollTop + 40;
        } else {
            alert("您已掉線,請重新進入聊天室...");
        }
    };

    function closeWs() {
        webSocket.close();
    };

    function initWebSocket() {
        var roomName = document.getElementById("input_roomName").value;
        var userName = document.getElementById("userName").value;
        // 房間名不能為空
        if (roomName == null || roomName == "") {
            alert("請輸入房間名");
            return;
        }
        var userJson = roomName+","+userName;
        if ("WebSocket" in window) {
            if (webSocket == null) {
                var url = "ws://127.0.0.1:8080/websocket/" + userJson;
                // 打開一個 web socket
                webSocket = new WebSocket(url);
            } else {
                alert("您已進入聊天室...");
            }
            webSocket.onopen = function () {
                heartCheck.reset().start();      //心跳檢測重置
                alert("已進入聊天室,暢聊吧...");
            };

            webSocket.onmessage = function (evt) {
                heartCheck.reset().start();      //拿到任何消息都說明當前連接是正常的
                var msg_board = document.getElementsByClassName("msg_board")[0];
                var received_msg = evt.data;
                var old_msg = msg_board.innerHTML;
                msg_board.innerHTML = old_msg + received_msg + "<br>";
                // 讓滾動塊往下移動
                msg_board.scrollTop = msg_board.scrollTop + 40;
            };

            webSocket.onclose = function () {
                // 關閉 websocket,清空信息板
                alert("連接已關閉...");
                webSocket = null;
                document.getElementsByClassName("msg_board")[0].innerHTML = "";
            };
        }
        else {
            // 瀏覽器不支持 WebSocket
            alert("您的瀏覽器不支持 WebSocket!");
        }
    }
    //websocket維持連接檢測
    var heartCheck = {
        timeout: 60000,        //1分鍾發一次
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(function(){
                //這里發送一個心跳,后端收到后,返回一個心跳消息,
                //onmessage拿到返回的心跳就說明連接正常
                webSocket.send("發送維持連接消息");
                 console.log("發送維持連接消息!")
                 self.serverTimeoutObj = setTimeout(function(){//如果超過一定時間還沒重置,說明后端主動斷開了
                     webSocket.close();     //如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
                 }, self.timeout)
            }, this.timeout)
        }
    }

后台代碼修改

// 收到客戶端消息后調用的方法
    @OnMessage  
    public void onMessage(String message, Session session) {  
        if(message.equals(""發送維持連接消息"")){
        }else{
        。。。。
        }
   }

 


免責聲明!

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



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