websocket onclose方法什么时候触发_WebSocket断开重连解决方案,心跳重连实践
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断开重连解决方案,心跳重连实践相关推荐
- WebSocket心跳重连机制
阅读本文章前请先了解WebSocket 场景 WebSocket在连接关闭的情况下会触发onclose事件,在链接异常的情况下会触发onerror事件.而在弱网条件下,onclose事件触发的灵敏度却 ...
- websocket receive方法内 有循环怎么退出_WebSocket了解一下
前言 这两天在调试一个WebSocket的接口,折腾了一天的时间终于弄好了.现在对WebSocket的相关知识点做一个记录.主要从如下几个方面进行介绍. WebSocket的概念 HTTP请求是基于请 ...
- websocket receive方法内 有循环怎么退出_认识HTML5的WebSocket
在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...
- c# websocket 心跳重连_websocket的简单使用
1.maven项目,第一步需要配置jar包 org.springframework.boot spring-boot-starter-websocket 2.前台使用 var websocket = ...
- websocket实现方法日志实时查询
本次方法的核心概念是通过redis生成唯一key值(没有放出来),然后通过前端获取这个唯一的key带入到方法请求中,然后服务器通过这个key生成此次方法生成唯一的日志文件,websocket接口通过线 ...
- php 析构不执行,PHP析构方法 __destruct() 不触发的两个解决办法
本篇文章主要给大家介绍PHP 析构方法 __destruct() 不触发的两个解决办法. 有时候在 PHP 里类循环引用时,会导致 __destruct() 不触发的问题,先上问题代码:<?ph ...
- python socketio_flask-socketio实现WebSocket的方法
[flask-socektio] 之前不知道在哪个场合下提到过如何从web后台向前台推送消息.听闻了反向ajax技术这种模式之后,大呼神奇,试了一下之后发现也确实可以用.不过,反向ajax的代价也很明 ...
- change()事件及val()/html()方法不会触发change事件
change()事件及val()/html()方法不会触发change事件 一.定义 change()函数用于为每个匹配元素的change事件绑定处理函数 当元素的值发生改变时,会发生 change ...
- form.submit 方法 并不会触发 form.onsubmit 事件
做表单的时候发现一个奇怪的地方,总结下: form.submit 方法 并不会触发 form.onsubmit 事件,看代码: <body><div class="cont ...
最新文章
- java输出回文数原代码_JAVA怎么用循环语句编写一个判别是否为回文数的代码?...
- while 小项目练习
- 仿windows造字程序的 ASP.NET图片组合生成控件
- Centos7把一个文件复制到另外一台服务器上的scp命令
- 为什么1000 == 1000返回为False,而100 == 100会返回为True?
- 楼继伟:现有5G技术很不成熟
- java和python互相调用
- C++实现设计模式——Builder模式
- 《Oracle Exadata云服务官方指南》之 Oracle Database Exadata 云服务
- Linux db2 54048,db2中SQLCODE=-1585,SQLSTATE=54048报错问题的解决
- golang 文件命名规则
- 初生牛犊不怕虎,管他呢! 干就是了。
- 哥伦比亚网银支付PSE
- 基于NaiveBayse SVM KNN的Python垃圾短信过滤系统 附代码
- table制作课程表案例
- git基于master创建新分支
- 使用 Excel 中的函数准确计算周岁年龄
- 监听队列中linux方法ss -a,Linux命令:ss命令
- 2018.1.28 牛客网2018年全国多校算法寒假训练营练习比赛题解
- jquery.slides.js 幻灯片脚本使用方法
热门文章
- Asp.Net Core 工作单元 UnitOfWork UOW
- python基础1 第一天
- Kali Linux2018 上安装open-vm-tools实现虚拟机交互
- poj3254 Corn Fields
- ASCII码、HEX、字符、BCD 等等 基础知识思考
- 【电脑使用经验】怎么查看无线网络中电脑的IP地址?
- 是用Entity.Save(),还是用DAL.Save(Entity e)
- node --- 在node中使用mongoosemongoDB的安装
- jquery --- 收缩兄弟元素
- 水瓶与天蝎的八年爱恋(图