1. 心跳重连原由

心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生。

websocket连接断开有以下两证情况:

前端断开

在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时关闭,这时候websocket的连接已经断开,而不同浏览器有不同的机制,触发onclose的时机也不同,并不会理想执行websocketonclose方法,我们无法知道是否断开连接,也就无法进行重连操作。

后端断开

如果后端因为一些情况需要断开ws,在可控情况下,会下发一个断连的消息通知,之后才会断开,我们便会重连。
如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了。

因此需要一种机制来检测客户端和服务端是否处于正常连接的状态。通过在指定时间间隔发送心跳包来保证连接正常,如果连接出现问题,就需要手动触发onclose事件,这时候便可进行重连操作。因此websocket心跳重连就应运而生。

2. 心跳重连的简单实现

2.1 通过createWebSocket创建连接

function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch');
reconnect(wsUrl);
}
}

2.2 创建init方法,初始化一些监听事件,如果希望websocket连接一直保持, 我们会在close或者error上绑定重新连接方法。

function init() {
ws.onclose = function () {
console.log('链接关闭');
reconnect(wsUrl);
};
ws.onerror = function() {
console.log('发生异常了');
reconnect(wsUrl);
};
ws.onopen = function () {
//心跳检测重置
heartCheck.start();
};
ws.onmessage = function (event) {
console.log('接收到消息');
//拿到任何消息都说明当前连接是正常的
heartCheck.start();
}
}

 2.3 重连操作,通过设置lockReconnect变量避免重复连接

var lockReconnect = false;//避免重复连接
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}

 2.4 心跳检测

//心跳检测
var heartCheck = {
timeout: 3000, //每隔三秒发送心跳
severTimeout: 5000, //服务端超时时间
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
var _this = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("123456789"); // 心跳包
//计算答复的超时时间
_this.serverTimeoutObj = setTimeout(function() {
ws.close();
}, _this.severTimeout);
}, this.timeout)
}
}

  有的时候,客户端发送3次心跳包服务端均未回复才判定为失去连接,所以这时需要加上计数来判断。

//心跳检测
var heartCheck = {
timeout: 3000, //每隔三秒发送心跳
num: 3, //3次心跳均未响应重连
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
var _this = this;
var _num = this.num;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("123456789"); // 心跳包
_num--;
//计算答复的超时次数
if(_num === 0) {
ws.colse();
}
}, this.timeout)
}
}

  最后总结下

我们确认了后端单台服务器的处理能力有限,因此。我们需要做集群。其次我们为了不让前端关闭或回收,后端不响应。我们需要设置心跳,定时清除无关的连接。
最后,我们需要有消息确认机制,做到保证消息的100%接收。

WebSocket心跳检测和重连机制的更多相关文章

  1. 【Netty】利用Netty实现心跳检测和重连机制

    一.前言 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制.   我们用到的很多框架都用到了心跳检测,比如服务注册到 Eureka Server 之后会维 ...

  2. javascript websocket 心跳检测机制介绍

    ====测试代码: ==index.html <!DOCTYPE html> <html lang="en"> <head> <meta ...

  3. 理解WebSocket心跳及重连机制(五)

    理解WebSocket心跳及重连机制 在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的 ...

  4. uni-app中websocket的使用 断开重连、心跳机制

    前言 最近关于H5和APP的开发中使用到了webSocket,由于web/app有时候会出现网络不稳定或者服务端主动断开,这时候导致消息推送不了的情况,需要客户端进行重连.查阅资料后发现了一个心跳机制 ...

  5. 初探和实现websocket心跳重连

    心跳重连缘由 在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开, 而浏览器不会执行websocket 的 onclos ...

  6. 初探和实现websocket心跳重连(npm: websocket-heartbeat-js)

    提示:文章最下方有仓库地址 心跳重连缘由 websocket是前后端交互的长连接,前后端也都可能因为一些情况导致连接失效并且相互之间没有反馈提醒.因此为了保证连接的可持续性和稳定性,websocket ...

  7. websocket心跳重连 websocket-heartbeat-js

    初探和实现websocket心跳重连(npm: websocket-heartbeat-js) 心跳重连缘由 websocket是前后端交互的长连接,前后端也都可能因为一些情况导致连接失效并且相互之间 ...

  8. Netty 之 Netty生产级的心跳和重连机制

    https://blog.csdn.net/z69183787/article/details/52625095 最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github ...

  9. 基于netty实现的长连接,心跳机制及重连机制

    技术:maven3.0.5 + netty4.1.33 + jdk1.8   概述 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...

随机推荐

  1. 第五十六篇:webpack的loader(四) -打包js中的高级语法

    好家伙, 1.打包处理js文件中的高级语法 webpack只能打包处理一部分高级的JavaScript 语法.对于那些webpack无法处理的高级js 语法,需要借 助于 babel-loader 进 ...

  2. Python工具箱系列(五)

    上一期介绍了Anaconda的安装,本期介绍Miniconda的安装,它们共同的部分是Conda,确实如此.Conda是一个开源的包管理系统,本身的志向非常宏大,要为Python. R. Ruby. ...

  3. 我的Vue之旅、01 深入Flexbox布局完全指南

    花了几个小时整合的"A Complete Guide to Flexbox"最新版本,介绍了flexbox的所有属性,外带几个实用的例子. 传统布局.Flexbox 布局的传统解决 ...

  4. linux使用iptables屏蔽ip地址

    一.iptables命令介绍: netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,在安装系统的时 ...

  5. 安装skywalking(测试使用)

    官方下载地址:https://skywalking.apache.org/downloads/ 需要: JDK8到JDK12已测试,其他版本未测试. # 在线安装jdk8 rpm -ivh https ...

  6. 常见Content-Type(MIME)列表

    Content-Type(MIME)用于标识发送或接收数据的类型,浏览器根据该参数来决定数据的打开方式.多用于指定一些客户端自定义的文件,以及一些媒体文件的打开方式. 文件扩展名 Content-Ty ...

  7. 通过nginx转发rabbitmq访问手动添加队列的时候报错:Management API returned status code 405

    原因: 正常访问该地址:https://xxx.xxx.com/rabbitmq/ 时能正常跳转,但是 rabbitmq management 的 API url 出现了 %2f 字符,这些字符会在经 ...

  8. 初等数论学习笔记 III:数论函数与筛法

    初等数论学习笔记 I:同余相关. 初等数论学习笔记 II:分解质因数. 1. 数论函数 本篇笔记所有内容均与数论函数相关.因此充分了解各种数论函数的名称,定义,符号和性质是必要的. 1.1 相关定义 ...

  9. 220722 T2 序列(ST表+分治)

    题目描述 小 B 喜欢玩游戏. 有一天,小 B 在玩一个序列上的游戏,他得到了正整数序列{ai}以及一个常数c . 游戏规则是,玩家可以对于每一个ai 分别加上一个非负整数x ,代价为 x2,完成所有 ...

  10. POJ3280 Cheapest Palindrome (区间DP)

    dp[i][j]表示将字符串子区间[i,j]转化为回文字符串的最小成本. 1 #include<cstdio> 2 #include<algorithm> 3 #include ...