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

bb2335ffad73526b08d685e7caf0aab9.png

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

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

    e5793ad49711612151f588fb257ff8c6.png

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

    在使用WebSocket的时候,如果网络突然断开,WebSocketd是不会触发任何事件的,所以前端程序无法得知当前链接是否断开。但是这个时候使用WebSocket.send方法的时候,浏览器会发现消息发不出去,隔一段时间之后(貌似每个浏览器隔的时间不相同),会触发onclose函数。利用这点9775052bbe25aa2aaae875bd3995e3b6.png,我们可以在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不出消息的时候重连的效果,测试的时候可以手动断网测,亲测有效a6e31c759ee3c2eb67e05bedc3038df0.png

好了,现在假设后端异常,没数据返回,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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261701.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab计算离散卷积

一.卷积的数学运算 (1)定义法 (2)图解法 (3)竖式乘法 二.matlab中计算离散卷积使用conv()函数 conv(a,b) 计算序列a与b的卷积 以上图中的习题为例 matlab代码如下: n1[ -2 -1 0 1 2 3 4 5]; …

黑马程序员_Java基础GUI

------- <a href"http://www.itheima.com" target"blank">android培训</a>、<a href"http://www.itheima.com" target"blank">java培训</a>、期待与您交流&#xff01; ---------- GUI:Graphical User Interf…

Maven中使用本地JAR包

为什么80%的码农都做不了架构师&#xff1f;>>> 在Maven项目中使用本地JAR包有两种方法&#xff1a; 1、使用system scope <dependencies><dependency><groupId>org.richard</groupId><artifactId>my-jar</artifactId><ver…

python文件读取方法read(size)的含义是_在Python中可使用read([size])来读取文件中的数据,如果参数size省略,则读取文件中的()。(4.0分)_学小易找答案...

【单选题】文本文件存储的是(),由若干文本行组成,通常每行以换行符 \n 结尾。(4.0分)【单选题】()属性是返回被打开文件的访问模式。(4.0分)【单选题】重力坝是由砼或( )修筑而成的大体积档水建筑物。【单选题】模式()的用途是打开一个文件用于追加。如果该文件已存在,文件指针…

折半查找法(二分查找法)

一.举例 二.算法时间复杂度 假设一共有n个元素 第一次折半元素个数变为n/2; 第二次折半元素个数变为n/4; 第三次折半元素个数变为n/8&#xff1b; 。。。。。 第k次折半元素个数变为n/2^k; 。。。。。 假设k次找到&#xff0c;即为n/2^k1&#xff1b; klog2(n); 三.函数实现 …

团队大事件-团队历程-团队记录~

团队名称&#xff1a; 河北大学信管团队 成立时间&#xff1a; 2010年7月8日 团队成员&#xff1a; 05&#xff1a;朱胜贤 07&#xff1a;孙旭峰 08&#xff1a;水亚亚 张文元 项玥 09&#xff1a;谢静 吕芳 吴凡 李亚慧 10&#xff1a; 第一组&#xff1a; 陈泰衡、李志伟…

Ubuntu链接ubuntu服务器

以前在windows下用ssh工具putty连接 linux服务器&#xff0c; 很简单&#xff0c;在linux下要连接linux的服务器&#xff0c; 找了下&#xff0c;果然putty在linux中也行1&#xff0c;sudo apt-get install putty安装后从applications中找到打开即可2. 直接用ssh登录ssh -l dev…

添加类iOS cocos2d 2游戏开发实战(第3版)

这两天一直在学习添加类之类的问题,现在正好有机会和大家讨论一下. 第1章 简介 1 1.1 第3版中的新增内容 2 1.2 选择ios版cocos2d的来由 3 1.2.1 收费 3 1.2.2 开源 4 1.2.3 objective-c 4 1.2.4 2d游戏引擎 4 1.2.5 物理引擎 4 1.2.6 技术难度较低 5 1.2.7 依然需要编…

悬浮截图软件_Windows最好用截图工具,QQ第一,它第二

大家平时可能都有自己惯用截图工具&#xff0c;比如 Snipaste、PickPick、QQ 截图&#xff0c;还有 Windows 自带的 WinShiftS 截图快捷键等等。如果你不是工具控&#xff0c;那一般来说 QQ 截图和 Windows 快截键就是最简单方便的两个截图工具了。但是真要说简单方便&#xff…

[摘记]数值方法04——函数求值

注&#xff1a;以下来自《C数值算法一书》&#xff0c;仅对章节内容做摘要&#xff0c;为的是给自己扫盲&#xff0c;不涉及算法。 这里只讨论一些最清晰明了的一般方法。 1. 级数与其收敛性 思想&#xff1a;解析函数可在某点x0的邻域内展开成级数&#xff1a;。用这个级数可以…

求两个数的最大公约数

一.基础款 #include <stdio.h> int main() {int m 0;int n 0;int i 0;int temp 0;int min 0;scanf_s("%d %d", &m, &n);if (m > n)min n;elsemin m;for (i 1; i < min / 2; i){if (m % i 0 && n % i 0)temp i;}printf("…

java文件处理之压缩,分割

http://blog.csdn.net/ycg01/article/details/1366648 java文件处理之压缩,分割 标签&#xff1a; javaexceptionimportnullbytefile2006-11-05 00:30 1574人阅读 评论(1) 收藏 举报分类&#xff1a;点滴&#xff08;12&#xff09; 版权声明&#xff1a;本文为博主原创文章&am…

成功通过pmp_这就是你为啥要学PMP!!!

好多学员一开始就会问&#xff0c;我为什么要学PMP&#xff0c;学这个对我到底有啥用啊&#xff1f;带着疑问&#xff0c;今天小编带你一起走进PMP&#xff01; PMP 证书价值&#xff1a; 1、很多国际国内公司要求项目经理持证上岗&#xff08;企业的投资、战略目标的实现多是依…

C# 判断给定大数是否为质数,目标以快速度得到正确的计算结果。

标题是一个测试题。在看到这道题的时候&#xff0c;第一反应这是一道考程序复杂度的题&#xff0c;其次再是算法问题。 我们先来看看质数的规则: Link&#xff1a;http://en.wikipedia.org/wiki/Prime_number C#求质数代码&#xff1a; 1 public bool primeNumber(int …

Hook KiUserExceptionDispatcher参数指针错误的问题

跟了一个晚上,终于解决了 大概要实现的是用这个函数替换ntdll中的KiUserExceptionDispatcher,实现方法如下: VOID NTAPI KiUserExceptionDispatcher(PEXCEPTION_RECORD pExcptRec,PCONTEXT pContext) { DWORD retValue; if (RtlDispatchException(pExcptRec,pContext)) { retVa…

Docker image Introduce

Docker 的image是运行的基本.例如我们build一个image时, 在Dockerfile每条指令会产生一个可读写的image, 下一条指令使用上一条指令产生的image为基础, 继续产生image(然后删除上一个image), 如果指令没有对image有修改的动作, 那么可以使用image cache. 所有的指令执行完, 生成…

vue 筛选组件_记一个复杂组件(Filter)的从设计到开发

此文前端框架使用 rax&#xff0c;全篇代码暂未开源&#xff08;待开源&#xff09;原文链接地址&#xff1a;Nealyang/PersonalBlog前言貌似在面试中&#xff0c;你如果设计一个 react/vue 组件&#xff0c;貌似已经是司空见惯的问题了。本文不是理论片&#xff0c;更多的是自…

Adobe称Flash技术遭排斥 呼吁政府介入

据国外媒体昨日报道&#xff0c;Adobe在一份提交给美国证交会的申报文件中抱怨称&#xff0c;Flash技术遭到苹果的全面排斥&#xff0c;这有可能对Adobe的业务产生影响。一位业内人士指出&#xff0c;此举彰显出Adobe可能要求政府机构的介入。 呼吁政府介入苹果旗下iPod Touch、…

python的正则表达式 re

2019独角兽企业重金招聘Python工程师标准>>> 原文发表在&#xff1a; http://luy.li/2010/05/12/python-re/ 延伸阅读&#xff1a;python的 内建函数 和 subprocess 。此文是本系列的第三篇文章了&#xff0c;和之前一样&#xff0c;内容出自官方文档&#xff0c;但…

python爬取图书信息_Python3 爬虫爬取中国图书网(淘书团) 记录

本人为一名刚开始学Python爬虫的小白&#xff0c;开贴仅为记录下自己的学习历程&#xff0c;方便做review要爬取链接&#xff1a;http://tuan.bookschina.com/要爬取内容&#xff1a; 图书名称&#xff0c; 图书价格&#xff0c; 以及对应预览图的link本文用到py packages: req…