关于WebSocket的心跳重连机制(详解)

前言

遇到的问题:
实时聊天过程中,
1、websocket连接后,长时间远端和客户端不发消息,服务端会把websocket给断开;
2、所以就需要一种机制来检测客户端和服务端是否处于正常的链接状态。
3、因此就有了websocket的‘心跳监测’。
4、还有心跳,说明还活着,没有心跳说明已经断开了。

websocket基础使用

基础使用

心跳机制

1、心跳机制是每隔一段时间会向服务器发送一个数据包:
	告诉服务器(后台)自己还活着,同时客户端(浏览器)会确认服务器端是否还活着
2、如果还活着的话,就会回传一个数据包给客户端
3、服务端断开连接了。客户端需要重连~

实现:

  1. 初始化建立websocket连接,websocket监听事件
init(row) {
    this.connectSocket() // 建立websocket连接
    this.socket.onopen = (e) => {
        console.log('Connection to server opened');
        // 连接成功执行的逻辑
    }
    // websocket连接接收消息后监听事件
    this.socket.onmessage = async(msg) => {
        try {
            var data = JSON.parse(msg.data)
            console.log(data)
        } catch(err){
            return
        }
        // websocket连接接收消息处理逻辑
    }
},
// 连接websocket
        connectSocket() {
            var address = window.location.hostname
            var protocol = 'ws'
            if (location.protocol === 'https:') {
                protocol = 'wss'
            }
            var url = ''
            url = protocol+'://'+location.host+`proxy代理字段`+'/websocket/'+`后台所需参数` 
            this.socket = this.createWebSocket(url)
            // 监听连接失败
            this.socket.onerror = this.websocketonerror
            // 监听连接关闭
            this.socket.onclose = this.websocketclose
        },
websocketonerror () { // 监听连接失败
            console.log('websocket连接断开')
            this.connectSocket()
          },
 websocketclose (e) { // 监听连接
     console.log('断开连接', e)
     this.connectSocket() // websocket关闭链接重连
 },

 // 创建websocket对象
 createWebSocket(url) {
     console.log(url)
     try{
         if(window.WebSocket)
             return new WebSocket(url);
         if(window.MozWebSocket)
             return new MozWebSocket(url);
     } catch(e) {
     }
     return false;
 },
  1. 心跳监测
1、什么时候进行心跳监测
2、逻辑代码
3、什么时候重置心跳监测
4、关闭心跳监测

websocket连接成功进行监测心跳

init(row) {
   this.connectSocket()
   this.socket.onopen = (e) => {
       console.log('Connection to server opened');
++    this.longstart();   // 成功建立连接后,创建心跳检测
       // 连接成功执行的逻辑
   }
   this.socket.onmessage = async(msg) => {
       try {
           var data = JSON.parse(msg.data)
           console.log(data)
       } catch(err){
           return
       }
       // websocket连接接收消息处理
   }
},

接收消息后进行心跳重置

 init(row) {
    this.connectSocket()
    this.socket.onopen = (e) => {
        console.log('Connection to server opened');
	    this.longstart();   // 成功建立连接后,创建心跳检测
        // 连接成功执行的逻辑
    }
    this.socket.onmessage = async(msg) => {
++    	console.log('心跳重置')
++        this.longstart();
        try {
            var data = JSON.parse(msg.data)
            console.log(data)
        } catch(err){
            return
        }
        // websocket连接接收消息处理
    }
},

逻辑代码-所需数据

data(){
	return {
		timeoutObj:undefined,
       serverTimeoutObj:undefined,
       socket:undefined
	}
}
longstart() {
			//1、通过关闭定时器和倒计时进行重置心跳
           clearInterval(this.timeoutObj)
           clearTimeout(this.serverTimeoutObj);
           // 2、每隔30s向后端发送一条商议好的数据
           this.timeoutObj = setInterval(()=>{
               console.log('重置监测心跳')
               let data={ // 与后端商量好心跳要传递的值
                   content: "pong",
                   contentType: "hert"
               }
               this.socket.send(JSON.stringify(data))
               // 3、发送数据 2s后没有接收到返回的数据进行关闭websocket重连
               this.serverTimeoutObj = setTimeout(()=>{
                   console.log("后台挂掉,没有心跳了....");
                   console.log("打印websocket的地址:"+this.socket);
                   this.socket.close();
               }, 2000);
           },30000)
         },

关闭心跳机制

destroyed () {
       // 1、组件销毁时,关闭与服务器的连接
       if (this.socket) {
         this.socket.close() // 离开路由之后断开websocket连接
       }
       // 2、通过关闭计时器和倒计时关闭心跳监测
       clearInterval(this.timeoutObj)
       clearTimeout(this.serverTimeoutObj);
     },
注意事项
1、 由于我们的websocket连接关闭立即进行重连了,组件销毁时,
断开websocket连接又走了重连机制
2、 websocketclose (e) { // 关闭
     this.connectSocket()
},
3、 所以我们需要定义一个变量控制是组件销毁关闭的websocket
还是心跳监测重连时关闭的websocket

定义变量判断是组件销毁关闭的websocket,还是心跳监测重连时关闭的websocket

data(){
       return{
       		~~~~
++           lockReconnect:false // 为true时,是心跳重连的websocket断开连接
       }
   },
destroyed () {
       this.lockReconnect=false
       // 组件销毁时,关闭与服务器的连接
       if (this.socket) {
         this.socket.close() // 离开路由之后断开websocket连接
       }
       clearInterval(this.timeoutObj)
       clearTimeout(this.serverTimeoutObj);
     },
longstart() {
            clearInterval(this.timeoutObj)
            clearTimeout(this.serverTimeoutObj);
            // clearInterval(this.overTime)
            this.timeoutObj = setInterval(()=>{
                console.log('重置监测心跳')
                let data={
                    chatType:"hert",
                    receiverId: this.chatroomList.userId,
                    receiverName: this.chatroomList.userName,
                    senderAvatar: this.userInfo.avatar,
                    senderName: this.userInfo.userName,
                    content: "pong",
                    contentType: "hert"
                }
                this.socket.send(JSON.stringify(data))
                this.serverTimeoutObj = setTimeout(()=>{
 ++                   this.lockReconnect=true // 心跳重连设置为true
                    console.log("后台挂掉,没有心跳了....");
                    console.log("打印websocket的地址:"+this.socket);
                    this.socket.close();
                    // createWebSocket();
                }, 2000);
            },30000)
            // },110000)
          },
websocketclose (e) { // 关闭
    console.log('断开连接', e)
    //lockReconnect为true在进行重连
++     if(this.lockReconnect){
++         this.connectSocket()
++     }else{
++     }
 },
  • 28
    点赞
  • 148
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值