本文章主要介绍了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{ 
        。。。。 
        } 
   }

发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

java eclipse使用不同jdk版本详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。