
WebSocket是前后端交互的长连接,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。项目中,我们经常会使用WebSocket和服务器建立持久的连接。
    但是前后端也会因为某些不明因素链接断开(我就是因为经常断网 ),导致前后端都没有反馈的情况
),导致前后端都没有反馈的情况
    
所以为了保持链接的稳定性和持续性,心跳重连就必须整上去了

 ,也顺便记录一下实现心跳重连的流程
,也顺便记录一下实现心跳重连的流程
    在使用WebSocket的时候,如果网络突然断开,WebSocketd是不会触发任何事件的,所以前端程序无法得知当前链接是否断开。但是这个时候使用WebSocket.send方法的时候,浏览器会发现消息发不出去,隔一段时间之后(貌似每个浏览器隔的时间不相同),会触发onclose函数。利用这点 ,我们可以在send不出消息并触发onclose之后,进行重连
,我们可以在send不出消息并触发onclose之后,进行重连
当然后端也可能出现异常,他收到了这个消息,但是没响应回来,前端也收不到通知,差不多就是你给一个人打电话,那niao人不说话的情况,问题你还不知道他在不在。所以这种情况我们要隔段时间send一次,假如超过一定时间没收到回应,那就默认是异常了,就触发重连。
WebSocket的各个绑定事件:
let ws = new WebSocket(url);ws.onopen = function () {   //something}ws.onmessage = function (event) {   //something}ws.onclose = function () {    //something}ws.onerror = function () {    //something}好了,按照这个思路,开始:
// 心跳检测let heartCheck = {    timeout: 60000, // 超时时间    timer: null,    serverTimer: null,    reset: function(){        clearTimeout(this.timer);     this.start();    },    start: function(){        this.timer = setTimeout(function(){            ws.send('connectTest');        }, this.timeout)    }}定义了一个心跳检测,当open的时候,执行heartCheck.start()方法,然后onmessage收到信息之后调用heartCheck.reset()方法重置,这样每次onmessage就触发send,达到循环发送的效果。
当send失败的时候,隔一段时间会自动触发onclose,所以要在onclose的时候调用重连
ws.onclose = function () {    console.log('onclose');    reconnect();}重连的时候需要注意防止重复连接,还要设置延迟,避免请求太频繁
let lockReconnect  = false;/** * @method reconnect ws重新连接 * @description lockReconnect防止重复连接,时间戳避免在失败时候会频繁建立ws连接 */ function reconnect() {    if(lockReconnect) return;    lockReconnect = true;    //没连接上会一直重连,设置延迟避免请求过多    setTimeout(function () {        createWebSocket(); // 创建webSocket连接的方法        lockReconnect = false;    }, 2000);}如此上面流程就解决了如断网send不出消息的时候重连的效果,测试的时候可以手动断网测,亲测有效
好了,现在假设后端异常,没数据返回,onmessage就进不去,得另外想办法。所以在每次send的时候的setTimeout内再加一个setTimeout,就是,如果里面这个setTimeout执行了,那就不等了,我觉得他是挂了,重连。
// 心跳检测let heartCheck = {    timeout: 60000, // 超时时间    timer: null,    serverTimer: null,    reset: function(){        clearTimeout(this.timer);        clearTimeout(this.serverTimer);     this.start();    },    start: function(){        let ts = this;        this.timer = setTimeout(function(){            ws.send('connectTest');            // 超出时间内未响应就主动关闭链接,关闭链接会触发重连            ts.serverTimer = setTimeout(function(){                ws.onclose();            }, ts.timeout)                    }, this.timeout)    }}如果onmessage收到消息,执行了reset会清空所有的timer,重新计时, nice~~~。
这样就完成了websocket的心跳重连,归纳一下代码:
let lockReconnect = false; //避免重复连接let ws;// 心跳检测let heartCheck = {    timeout: 60000,    timer: null,    serverTimer: null,    reset: function(){        clearTimeout(this.timer);        clearTimeout(this.serverTimer);     this.start();    },    start: function(){        let ts = this;        this.timer = setTimeout(function(){            ws.send('connectTest');            ts.serverTimer = setTimeout(function(){                ws.onclose();            }, ts.timeout)        }, this.timeout)    }}// 创建WebSocket链接function createWebSocket () {    if ("WebSocket" in window) {        if (!url) return        ws = new WebSocket(url);                // WebSocket事件方法        initEventHandle();    } else {        console.log('您的浏览器不支持websocket')    }}/** * @method initEventHandle 初始化ws各个事件的方法 */function initEventHandle (url) {    ws.onopen = function () {        heartCheck.start();        console.log('链接成功:', url);    }    //获得消息事件    ws.onmessage = function(data, state) {        // 收到消息的时候重置倒计时        heartCheck.reset();                //something            }    ws.onerror = function() {        message('error', 'WebSocket连接错误!正在重连');        reconnect();    }    ws.onclose = function () {        console.log('onclose');        reconnect();    }}/** * @method reconnect ws重新连接 * @description lockReconnect防止重复连接,时间戳避免在失败时候会频繁建立ws连接 */function reconnect() {    if(lockReconnect) return;    lockReconnect = true;    //没连接上会一直重连,设置延迟避免请求过多    setTimeout(function () {        createWebSocket();        lockReconnect = false;    }, 2000);}