前言

为了获取实时数据,前端需要和后端保持通信,HTTP 协议只能是客户端向服务器发出请求,服务器返回查询结果。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。一般通过以下几种方式实现即时通讯。

即时通讯:短轮询、长链接、长轮询、websocket

短轮询的原理很简单,每隔一段时间客户端就发出一个请求,去获取服务器最新的数据, 一定程度上模拟实现了即时通讯。

优点:兼容性强,实现非常简单
缺点:延迟性高,非常消耗请求资源,影响性能

长轮询优缺点:

优点:兼容性好,资源浪费较小
缺点:服务器 hold连接会消耗资源,返回数据顺序无保证,难于管理维护

长连接优缺点:

优点:兼容性好,消息即时到达,不发无用请求
缺点:服务器维护长连接消耗资源

Websocket是一个全新的、独立的协议,基于 TCP协议,与 http协议兼容、却不会融入 http协议,仅仅作为 html5的一部分,其作用就是在服务器和客户端之间建立实时的双向 通信。

优点:真正意义上的实时双向通信,性能好,低延迟
缺点:独立与 http的协议,因此需要额外的项目改造,使用复杂度高,必须引入成熟的库,无法兼容低版本浏览器

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,在更多的时候一般都会采用websocket来实现即时通讯的需求。

WebSocket心跳及重连机制

websocket是前后端交互的长连接,在使用的过程中,遇到弱网或者网络暂时断连的情况时,服务端并没有触发onclose的事件,客户端也无法得知当前连接是否已经断开,服务端会继续向客户端发送多余链接,并且这些数据还会丢失。因此为了保证连接的可持续性和稳定性,我们需要有一套机制来检测客户端和服务端是否处于正常连接状态,websocket心跳重连就应运而生。

完整代码

创建websocket实例化的时候,一般会绑定各个回调事件需要执行的函数:

<html>
<head><meta charset="utf-8"><title>WebSocket Demo</title>
</head>
<body><script type="text/javascript">// var ws = new WebSocket("wss://echo.websocket.org");/*ws.onerror = function(e) {console.log('已关闭');};ws.onopen = function(e) {console.log('握手成功');ws.send('123456789');}ws.onclose = function() {console.log('已关闭');}ws.onmessage = function(e) {console.log('收到消息');console.log(e);}*/var lockReconnect = false;//避免重复连接var wsUrl = "wss://echo.websocket.org";var ws;var tt;function createWebSocket() {try {ws = new WebSocket(wsUrl);init();} catch(e) {console.log('catch');reconnect(wsUrl);}}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();}}function reconnect(url) {if(lockReconnect) {return;};lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多tt && clearTimeout(tt);tt = setTimeout(function () {createWebSocket(url);lockReconnect = false;}, 4000);}//心跳检测var heartCheck = {timeout: 3000,timeoutObj: null,serverTimeoutObj: null,start: function(){console.log('start');var self = this;this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(function(){//这里发送一个心跳,后端收到后,返回一个心跳消息,console.log('55555');ws.send("123456789");self.serverTimeoutObj = setTimeout(function() {console.log(111);console.log(ws);ws.close();// createWebSocket();}, self.timeout);}, this.timeout)}}createWebSocket(wsUrl);</script>
</body>
</html>

实现思路

1、第一步页面初始化,先调用createWebSocket函数,目的是创建一个websocket的方法:new WebSocket(wsUrl);因此封装成函数内如下代码:

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

2、第二步调用init方法,该方法内把一些监听事件封装如下:
当网络断开的时候,会先调用onerror,onclose事件可以监听到,会调用reconnect方法进行重连操作。正常的情况下,是先调用
onopen方法的,当接收到数据时,会被onmessage事件监听到。

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();}
}

3、重连操作 reconnect代码如下:
如果网络断开的话,会执行reconnect方法,使用了一个定时器,4秒后会重新创建一个新的websocket链接,重新调用createWebSocket函数,重新会执行及发送数据给服务器端。

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

4、 最后一步就是实现心跳检测的代码:

//心跳检测
var heartCheck = {timeout: 3000,timeoutObj: null,serverTimeoutObj: null,start: function(){console.log('start');var self = this;this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(function(){//这里发送一个心跳,后端收到后,返回一个心跳消息,//onmessage拿到返回的心跳就说明连接正常console.log('55555');ws.send("123456789");self.serverTimeoutObj = setTimeout(function() {console.log(111);console.log(ws);ws.close();// createWebSocket();}, self.timeout);}, this.timeout)}
}

更多文章__> >> 码砖猿的技术博客

Websocket心跳检测、重连机制相关推荐

  1. websocket心跳检测

    1.心跳检测的缘由 websocket心跳检测的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生. websocket断开一般有两种情况 前端断开 在使用websocket过程中,可能会 ...

  2. websocket心跳检测前后端架构

    websocket心跳检测前后端架构 本篇文章为初略架构websocket在前后端的心跳检测机制,实现相对毛糙. 下面介绍内容参照 廖雪峰 的描述,为了切换页面麻烦,这里就直接挑简要的信息复制黏贴过来 ...

  3. websocket心跳链接代码_WebSocket原理与实践(五)--心跳及重连机制

    在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失.所以就需要 ...

  4. 微信小程序WebSocket心跳检测与断来重连

    为什么要心跳检测 使用微信小程序WebSocket时,WebSocket在一定的时间没有进行通信就会断开连接,所以需要使用心跳检测. 那么心跳检测是什么呢,心跳检测顾名思义就是和人心脏动一样,客户端在 ...

  5. Netty下的WebSocket心跳检测

    什么是心跳检测 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制. 在WebSocket中即判断套接字是否已经与服务器断开,无法使用,此时要清理服务器的该 ...

  6. php websocket 心跳包,websocket 心跳包重连

    上次我们讲过了websocket断线重连的问题,那么久会有人提出疑问了,心跳包重连跟断线重连有什么区别呢? 其实这两个都是为了达到一个目的,那就是保证当前设备的网络状态保持通畅...而断线重连呢,只能 ...

  7. paho架构_MQTT系列最终章-Paho源码分析(三)-心跳与重连机制

    写在前面 通过之前MQTT系列-Eclipse.Paho源码分析(二)-消息的发送与接收的介绍,相信仔细阅读过的小伙伴已经对Eclipse.Paho内部发送和订阅消息的流程有了一个较为清晰的认识,今天 ...

  8. WebSocket的心跳重连机制

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

  9. WebSocket心跳

    理解WebSocket心跳及重连机制(五) - 百度文库 情况:当客户端网络断开无法接收信息,服务端依旧持续向客户端发送信息,造成数据丢失. 所以就需要一种机制检测客户端和服务端是否处于正常链接的状态 ...

最新文章

  1. 2020 北京智源大会首日精华速递
  2. Reddit年度盘点:2019年最佳机器学习项目
  3. android调用unity,大神们,请问unity和Android交互的时候,为什么总是调用不到方法...
  4. HDU 1412 {A} + {B}
  5. 解决SELinux导致Apache更改端口后无法启动的问题
  6. python 取名字_python 获取如何获取类的名称?
  7. java中线性结构的例子_java数据结构--线性结构
  8. 数据库MySQL/mariadb知识点——日志记录(2)二进制日志
  9. 从人脸识别到内容审核,百度硬核AI技术推荐!
  10. 利用已有的大数据技术,如何构建机器学习平台
  11. oracle建表的方法,oracle建表语句
  12. 实验误差分析大全,实验员必备!
  13. 单片机c语言双电源程序,基于单片机的双电源自动切换开关控制器
  14. 计算机实验环境怎么写visual,visualfoxpro计算机实验报告答案
  15. python xlsxwriter下载_python_xlsxwriter模块
  16. 将Excel表格导入到数据库中
  17. SMILES, a Chemical Language and Information System.【SMILES, 一种化学语言和信息系统。】
  18. 交换字符使得字符串相同
  19. java输入十个,键盘输入十个数,输出最大数
  20. 3.2【微信小程序全栈开发课程】登录功能(一)--实现登录功能

热门文章

  1. 实验五 集成运放组成的基本运算电路
  2. LMT下extent的分配
  3. java后台生成并下载二维码
  4. 【算法讲18:二次剩余】勒让德符号 | 欧拉判别法 | Cipolla 算法
  5. 2022年电赛 声源定位跟踪系统(E题)
  6. numpy奇异值分解,广义逆矩阵与行列式
  7. B19 - 999、大数据组件学习⑯ - ElasticSearch
  8. Android 音频录制 的三种方式
  9. 键盘摄影:今天老李是一名动物摄影师
  10. java 网络编程和NIO