做websocket链接的时候不得不考虑的情况就是断线重连的情况,在一个websocket被建立之后若服务端的程序跑飞了,这个websocket连接将处于一种未知
的状态。
为了避免这种情况的出现:我们通常用心跳信息来保证连接的存活:
在Vue中的代码如下:
methods: {
initWebSocket () {
let that = this
if (this.ws) {
this.ws.close()
delete this.ws
}
that.subSysSockt = new WebSocket(airWsuri)
that.subSysSockt.onopen = this.openWs
that.subSysSockt.onmessage = this.reviceMsg
// 这里的onerror只有在前端websocket发生异常时才会触发
that.subSysSockt.onerror = this.wserr
// 这里的onclose只有在前端主动关闭websocket时才会触发
that.subSysSockt.onclose = this.reConnect
that.timer = setInterval(() => {
if (that.subSysSockt.readyState === 1) {
/*
重连的思路: 每次前端往后端发送心跳信息,若心跳信息发出去2秒钟后未收到后端的回应
则关闭这个websocket连接,重新建立websocket链接
*/
that.subSysSockt.send("test")
// 这个waitMsg用于判断是否收到服务端回的心跳信息
this.waitMsg = false
that.timerWait = setTimeout(() => {
if (that.waitMsg === false) {
console.log('重连websocket...')
clearInterval(that.timer)
clearTimeout(that.timerWait)
that.subSysSockt.close()
that.initWebSocket()
} else {
clearTimeout(that.timerWait)
}
}, 2000)
}
}, 20000)
},
reviceMsg (event) {
// 收到消息时标志置为true
this.waitMsg = true
clearTimeout(this.timerWait)
try {
let message = JSON.parse(event.data)
// 2020-6-22 临时解决方法(deviceType为2006和2008的设备就是要显示的设备)
this.device = message.deviceNumInfoList.filter(e => e.deviceType === 2006 || e.deviceType === 2008)
} catch (e) {
// replay异常暂时不处理...
}
},
openWs () {
if (this.subSysSockt.readyState === 1) {
let that = this
let subscribeSys = {
"system_id": 1000
}
// 获取报警视频列表
that.subSysSockt.send(JSON.stringify(subscribeSys))
}
},
reConnect () {
let self = this
this.timer2 = setInterval(() => {
if (self.subSysSockt.readyState === 3) {
self.subSysSockt = new WebSocket(airWsuri)
clearInterval(this.timer2)
}
}, 2000)
},
......
}
网友评论