WebSocket是前后端交互的长连接,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。项目中,我们经常会使用WebSocket和服务器建立持久的连接。

但是前后端也会因为某些不明因素链接断开(我就是因为经常断网),导致前后端都没有反馈的情况

所以为了保持链接的稳定性和持续性,心跳重连就必须整上去了,也顺便记录一下实现心跳重连的流程

在使用WebSocket的时候,如果网络突然断开,WebSocketd是不会触发任何事件的,所以前端程序无法得知当前链接是否断开。但是这个时候使用WebSocket.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);}

websocket onclose方法什么时候触发_WebSocket断开重连解决方案,心跳重连实践相关推荐

  1. WebSocket心跳重连机制

    阅读本文章前请先了解WebSocket 场景 WebSocket在连接关闭的情况下会触发onclose事件,在链接异常的情况下会触发onerror事件.而在弱网条件下,onclose事件触发的灵敏度却 ...

  2. websocket receive方法内 有循环怎么退出_WebSocket了解一下

    前言 这两天在调试一个WebSocket的接口,折腾了一天的时间终于弄好了.现在对WebSocket的相关知识点做一个记录.主要从如下几个方面进行介绍. WebSocket的概念 HTTP请求是基于请 ...

  3. websocket receive方法内 有循环怎么退出_认识HTML5的WebSocket

    在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...

  4. c# websocket 心跳重连_websocket的简单使用

    1.maven项目,第一步需要配置jar包 org.springframework.boot spring-boot-starter-websocket 2.前台使用 var websocket = ...

  5. websocket实现方法日志实时查询

    本次方法的核心概念是通过redis生成唯一key值(没有放出来),然后通过前端获取这个唯一的key带入到方法请求中,然后服务器通过这个key生成此次方法生成唯一的日志文件,websocket接口通过线 ...

  6. php 析构不执行,PHP析构方法 __destruct() 不触发的两个解决办法

    本篇文章主要给大家介绍PHP 析构方法 __destruct() 不触发的两个解决办法. 有时候在 PHP 里类循环引用时,会导致 __destruct() 不触发的问题,先上问题代码:<?ph ...

  7. python socketio_flask-socketio实现WebSocket的方法

    [flask-socektio] 之前不知道在哪个场合下提到过如何从web后台向前台推送消息.听闻了反向ajax技术这种模式之后,大呼神奇,试了一下之后发现也确实可以用.不过,反向ajax的代价也很明 ...

  8. change()事件及val()/html()方法不会触发change事件

    change()事件及val()/html()方法不会触发change事件 一.定义 change()函数用于为每个匹配元素的change事件绑定处理函数 当元素的值发生改变时,会发生 change ...

  9. form.submit 方法 并不会触发 form.onsubmit 事件

    做表单的时候发现一个奇怪的地方,总结下: form.submit 方法 并不会触发 form.onsubmit 事件,看代码: <body><div class="cont ...

最新文章

  1. java输出回文数原代码_JAVA怎么用循环语句编写一个判别是否为回文数的代码?...
  2. while 小项目练习
  3. 仿windows造字程序的 ASP.NET图片组合生成控件
  4. Centos7把一个文件复制到另外一台服务器上的scp命令
  5. 为什么1000 == 1000返回为False,而100 == 100会返回为True?
  6. 楼继伟:现有5G技术很不成熟
  7. java和python互相调用
  8. C++实现设计模式——Builder模式
  9. 《Oracle Exadata云服务官方指南》之 Oracle Database Exadata 云服务
  10. Linux db2 54048,db2中SQLCODE=-1585,SQLSTATE=54048报错问题的解决
  11. golang 文件命名规则
  12. 初生牛犊不怕虎,管他呢! 干就是了。
  13. 哥伦比亚网银支付PSE
  14. 基于NaiveBayse SVM KNN的Python垃圾短信过滤系统 附代码
  15. table制作课程表案例
  16. git基于master创建新分支
  17. 使用 Excel 中的函数准确计算周岁年龄
  18. 监听队列中linux方法ss -a,Linux命令:ss命令
  19. 2018.1.28 牛客网2018年全国多校算法寒假训练营练习比赛题解
  20. jquery.slides.js 幻灯片脚本使用方法

热门文章

  1. Asp.Net Core 工作单元 UnitOfWork UOW
  2. python基础1 第一天
  3. Kali Linux2018 上安装open-vm-tools实现虚拟机交互
  4. poj3254 Corn Fields
  5. ASCII码、HEX、字符、BCD 等等 基础知识思考
  6. 【电脑使用经验】怎么查看无线网络中电脑的IP地址?
  7. 是用Entity.Save(),还是用DAL.Save(Entity e)
  8. node --- 在node中使用mongoosemongoDB的安装
  9. jquery --- 收缩兄弟元素
  10. 水瓶与天蝎的八年爱恋(图