WebSocket心跳
为什么要实现websocket心跳?
在使用原生websocket的时候,如果设备网络断开,不会触发任何函数,前端程序无法得知当前的连接已经断开,这个时候如果调用 websocket.send()方法,浏览器就会发现消息发不出去,便会立刻或一定短时间后(不同浏览器或浏览器版本可能表现不同)触发onclose函数。
1.页面初始化调用initWebSocket函数,目的是创建一个websocket方法
let isLockReconnect = false //避免重复连接
let wsUrl = 'ws://xxx.xx.xx'
let ws = null
let reconnectTimer = null
let reconnectDelayTime = 10000;//重复连接延迟时间,避免一直重复连接
let heartCheckIntervalTime = 30000;//心跳检测间隔时间
function initWebSocket(){
try{
ws = new WebSocket(wsUrl)
wsMonitor()
}catch(e){
console.log(e)
reconnect(wsUrl)
}
}
2.实现wsMonitor方法,该方法内把一些监听事件进行封装
function wsMonitor (){
ws.onclose = ()=>{
console.log('连接关闭')
reconnect(wsUrl)
}
ws.onerror = ()=>{
console.log('发生异常')
reconnect(wsUrl)
}
ws.onopen = ()=>{
console.log('连接打开')
heartCheck.start()
}
ws.onmessage = ()=>{
console.log('接收到消息')
heartCheck.start()
}
}
当网络断开,onerror,onclose事件可以监听到,会调用reconnect方法进行重连操作,正常情况下联通成功onopen方法会监听到,接收到数据时会被onmessage事件监听到
3.重连操作reconnect方法实现
function reconnect(wsUrl){
if(isLockReconnect){
return
}
isLockReconnect = true;
reconnectTimer && clearTimeout(reconnectTimer)
reconnectTimer = setTimeout(()=>{
initWebSocket(wsUrl)
isLockReconnect = false
},reconnectDelayTime)//设置延迟连接
}
4.实现心跳监测代码(个人理解:关键点在heartCheck.start方法;)
- onopen、onmessage都执行heartCheck.start方法
- 间隔heartCheckIntervalTime时间询问是否断联
- 若未断联,onmessage再次执行heartCheck.start方法,则清除定时器
- 若断联,执行ws.close方法(内部逻辑进行重连)
let heartCheck = {
timeoutObj:null,
serverTimeoutObj:null,
start(){
this.timeoutObj && clearTimeout(this.timeoutObj)
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
this.timeoutObj = setTimeout(()=>{
ws.send('Is Server Alive?')
this.timeoutObj = null
this.serverTimeoutObj = setTimeout(()=>{
ws.close()
this.serverTimeoutObj = null
},heartCheckIntervalTime)
},heartCheckIntervalTime)
}
}
构造函数版
class WebSocketHeart{
constructor(wsUrl){
this.isLockConnect = false //是否锁死重复连接
this.wsUrl = wsUrl //websocketURL地址
this.ws = null //websocket实例对象
this.reconnectTimer = null //重连定时器
this.reconnectDelayTime = 10000 //重连延迟时间
this.heartCheckInterValTime = 30000 //心跳检测间隔时间
this.timeoutObj = null //心跳检测定时器
this.serverTimeoutObj = null //心跳检测服务端定时器
}
initWebSocket(){
try{
this.ws = new WebSocket(this.wsUrl)
this.wsMonitor()
}catch(err){
console.log(err)
this.reconnect()
}
}
wsMonitor(){
this.ws.onclose = () => {
console.log('连接关闭')
this.reconnect(this.wsUrl)
}
this.ws.onerror = () => {
console.log('连接错误')
this.reconnect(this.wsUrl)
}
this.ws.onopen = () => {
console.log('连接打开')
this.heartCheck()
}
this.ws.onmessage = () => {
console.log('接收消息')
this.heartCheck()
}
}
reconnect(wsUrl){
if(!this.isLockConnect){
return
}
this.isLockConnect = true
this.reconnectTimer && clearTimeout(this.reconnectTimer)
this.reconnectTimer = setTimeout(()=>{
this.initWebSocket(wsUrl)
this.isLockConnect = false
},this.reconnectDelayTime)
}
heartCheck(){
this.timeoutObj && clearTimeout(this.timeoutObj)
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
this.timeoutObj = setTimeout(() => {
this.ws.send('Is Server Alive ?')
this.timeoutObj = null
this.serverTimeoutObj = setTimeout(() => {
this.ws.close()
this.serverTimeoutObj = null
},this.heartCheckInterValTime)
},this.heartCheckInterValTime)
}
}
以自己现在的努力程度,还没有资格和别人拼天赋

浙公网安备 33010602011771号