WebSocket 心跳检测和重连机制

为什么会进行心跳检测

简单地说是为了证明客户端和服务器还活着。websocket 在使用过程中,如果遭遇网络问题等,这个时候服务端没有触发onclose事件,这样会产生多余的连接,并且服务端会继续发送消息给客户端,造成数据丢失。因此需要一种机制来检测客户端和服务端是否处于正常连接的状态,心跳检测和重连机制就产生了。

如何进行心跳检测和重连

思路是

  1. 每隔一段指定的时间(计时器),向服务器发送一个数据,服务器收到数据后再发送给客户端,正常情况下客户端通过onmessage事件是能监听到服务器返回的数据的,说明请求正常。
  2. 如果再这个指定时间内,客户端没有收到服务器端返回的响应消息,就判定连接断开了,使用websocket.close关闭连接。
  3. 这个关闭连接的动作可以通过onclose事件监听到,因此在 onclose 事件内,我们可以调用reconnect事件进行重连操作。

具体代码实现

$(function () {
    var path = basePath;
    var jspCode = $("#userId").val();
    var websocket;
    createWebSocket();

    /**
     * websocket启动
     */
    function createWebSocket() {
        try {
            if ('WebSocket' in window) {
                websocket = new WebSocket((path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws"));
            } else if ('MozWebSocket' in window) {
                websocket = new MozWebSocket(("ws://" + path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws"));
            } else {
                websocket = new SockJS(path + "/wsCrm/sockJs?jspCode=" + jspCode.replace("http", "ws"));
            }
            init();
        } catch (e) {
            console.log('catch' + e);
            reconnect();
        }

    }

    function init() {
        //连接成功建立的回调方法
        websocket.onopen = function (event) {
            console.log("WebSocket:已连接");
            //心跳检测重置
            heartCheck.reset().start();
        };

        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            showNotify(event.data);
            console.log("WebSocket:收到一条消息", event.data);
            heartCheck.reset().start();
        };

        //连接发生错误的回调方法
        websocket.onerror = function (event) {
            console.log("WebSocket:发生错误");
            reconnect();
        };

        //连接关闭的回调方法
        websocket.onclose = function (event) {
            console.log("WebSocket:已关闭");
            heartCheck.reset();//心跳检测
            reconnect();
        };

        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            websocket.close();
        };

        //关闭连接
        function closeWebSocket() {
            websocket.close();
        }

        //发送消息
        function send(message) {
            websocket.send(message);
        }
    }

    //避免重复连接
    var lockReconnect = false, tt;

    /**
     * websocket重连
     */
    function reconnect() {
        if (lockReconnect) {
            return;
        }
        lockReconnect = true;
        tt && clearTimeout(tt);
        tt = setTimeout(function () {
            console.log('重连中...');
            lockReconnect = false;
            createWebSocket();
        }, 4000);
    }

    /**
     * websocket心跳检测
     */
    var heartCheck = {
        timeout: 5000,
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function () {
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function () {
            var self = this;
            this.timeoutObj && clearTimeout(this.timeoutObj);
            this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
            this.timeoutObj = setTimeout(function () {
                //这里发送一个心跳,后端收到后,返回一个心跳消息,
                //onmessage拿到返回的心跳就说明连接正常
                websocket.send("HeartBeat");
                console.log('ping');
                self.serverTimeoutObj = setTimeout(function () { // 如果超过一定时间还没重置,说明后端主动断开了
                    console.log('关闭服务');
                    websocket.close();//如果onclose会执行reconnect,我们执行 websocket.close()就行了.如果直接执行 reconnect 会触发onclose导致重连两次
                }, self.timeout)
            }, this.timeout)
        }
    };
});
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Websocket是基于TCP协议的双向通信协议,由于网络的不稳定性,可能会出现连接断开的情况。为了避免这种情况,我们可以采用心跳检测重连机制来保证Websocket连接的稳定性。 1. 心跳检测 心跳检测是指定时向服务端发送一个特定的消息来确认连接是否正常。如果服务端在一定时间内没有收到客户端发送的心跳消息,就可以断开连接。 客户端可以通过以下几种方式实现心跳检测: - 定时发送心跳包:客户端定时向服务端发送心跳包,服务端收到后就知道客户端还在连接。 - 客户端主动询问服务端:客户端可以发送一个询问消息给服务端,服务端如果收到了这个消息就说明客户端还在连接。 - 采用WebSocket API中的ping/pong机制WebSocket API提供了ping/pong机制,客户端可以发送ping消息给服务端,服务端收到后就会回复pong消息,客户端收到pong消息就说明连接还在。 2. 重连机制Websocket连接断开后,客户端需要采取一些措施来重新建立连接。常见的重连机制有以下几种: - 定时重连:客户端可以定时尝试重新连接服务端,这种方式简单,但可能会浪费资源。 - 指数退避算法:客户端在重连时可以采用指数退避算法,每次重连的时间间隔逐渐增加,避免重连时同时向服务端发送大量请求。 - 使用备用服务器:客户端可以在连接断开时尝试连接备用服务器,如果备用服务器可以正常工作,就可以避免连接中断的情况。 以上就是Websocket心跳检测重连机制的介绍,希望能够对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值