1.直接上代码
let ws //websocket实例
let lockReconnect = false //避免重复连接
let wsUrl = ''
//初始化websocket
getWebSocketurl()
async function getWebSocketurl() {
try {
// const data = await getInfo()
sid.value = localStorage.getItem('Refresh-Token')
wsUrl = `ws://192.168.2.158/webSocket/${sid.value}`
createWebSocket(wsUrl)
} catch (e) {
console.log(e)
}
}
//前面都是准备工作
async function createWebSocket(url) {
try {
ws = new WebSocket(wsUrl) //创建websocket链接
initEventHandle() //后续操作
} catch (e) {
reconnect(url)
}
}
function initEventHandle() {
ws.onclose = function (evnt) {
console.log('websocket服务关闭了')
reconnect(wsUrl)
}
ws.onerror = function (evnt) {
console.log('websocket服务出错了')
reconnect(wsUrl)
}
ws.onopen = function (evnt) {
console.log('websocket服务开始')
sendMsg.value = JSON.stringify(sendMsg.value)
ws.send(sendMsg.value)
//心跳检测重置
heartCheck.reset().start()
}
ws.onmessage = function (evnt) {
//如果获取到消息,心跳检测重置
//拿到任何消息都说明当前连接是正常的
console.log('websocket服务获得数据了')
//接受消息后的UI变化
doWithMsg(evnt.data) //收到消息进行页面操作
//心跳检测重置
heartCheck.reset().start()
}
//收到消息推送
function doWithMsg(msg) {
// 收到消息操作页面、、
}
function reconnect(url) {
if (lockReconnect) return
lockReconnect = true
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () {
createWebSocket(url)
lockReconnect = false
}, 2000)
}
//心跳检测
let heartCheck = {
timeout: 600000, //60秒
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimeoutObj)
return this
},
start: function () {
let self = this
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
// ws.send('HeartBeat')
ws.send(sendMsg.value)
self.serverTimeoutObj = setTimeout(function () {
//如果超过一定时间还没重置,说明后端主动断开了
ws.close() //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
},
}
2.另一种
<template>
</template>
<script>
import store from '@/store'
export default {
props: {
uri: {
type: String
},
},
data() {
return {
webSocket: null, // webSocket实例
lockReconnect: false, // 重连锁,避免多次重连
maxReconnect: 6, // 最大重连次数, -1 标识无限重连
reconnectTime: 0, // 重连尝试次数
heartbeat: {
interval: 30 * 1000, // 心跳间隔时间
timeout: 10 * 1000, // 响应超时时间
pingTimeoutObj: null, // 延时发送心跳的定时器
pongTimeoutObj: null, // 接收心跳响应的定时器
pingMessage: JSON.stringify({type: 'ping'}) // 心跳请求信息
}
}
},
computed: {
token() {
return store.getters.access_token
},
tenant() {
return store.getters.userInfo.tenantId ? store.getters.userInfo.tenantId : 1;
}
},
created() {
this.initWebSocket()
},
destroyed: function () {
this.webSocket.close()
this.clearTimeoutObj(this.heartbeat)
},
methods: {
/**
* 初始化 weoSocket
*/
initWebSocket() {
// ws地址
let host = window.location.host;
let wsUri = `ws://${host}${this.uri}?access_token=${this.token}&TENANT-ID=${this.tenant}`
// 建立连接
this.webSocket = new WebSocket(wsUri)
// 连接成功
this.webSocket.onopen = this.onOpen
// 连接错误
this.webSocket.onerror = this.onError
// 接收信息
this.webSocket.onmessage = this.onMessage
// 连接关闭
this.webSocket.onclose = this.onClose
},
/**
* 重新连接
*/
reconnect() {
if (!this.token) {
return
}
if (this.lockReconnect || (this.maxReconnect !== -1 && this.reconnectTime > this.maxReconnect)) {
return
}
this.lockReconnect = true
setTimeout(() => {
this.reconnectTime++
// 建立新连接
this.initWebSocket()
this.lockReconnect = false
}, 5000)
},
/**
* 清空定时器
*/
clearTimeoutObj: function (heartbeat) {
heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj)
heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj)
},
/**
* 开启心跳
*/
startHeartbeat() {
const webSocket = this.webSocket
const heartbeat = this.heartbeat
// 清空定时器
this.clearTimeoutObj(heartbeat)
// 延时发送下一次心跳
heartbeat.pingTimeoutObj = setTimeout(() => {
// 如果连接正常
if (webSocket.readyState === 1) {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
webSocket.send(heartbeat.pingMessage)
// 心跳发送后,如果服务器超时未响应则断开,如果响应了会被重置心跳定时器
heartbeat.pongTimeoutObj = setTimeout(() => {
webSocket.close()
}, heartbeat.timeout)
} else {
// 否则重连
this.reconnect()
}
}, heartbeat.interval)
},
/**
* 连接成功事件
*/
onOpen() {
console.log('WebSocket connection success')
//开启心跳
this.startHeartbeat()
this.reconnectTime = 0
},
/**
* 连接失败事件
* @param e
*/
onError(e) {
//错误
console.log(`WebSocket connection error:${e.code} ${e.reason} ${e.wasClean}`)
//重连
this.reconnect()
},
/**
* 连接关闭事件
* @param e
*/
onClose(e) {
//关闭
console.log(`WebSocket connection closed:${e.code} ${e.reason} ${e.wasClean}`)
//重连
this.reconnect()
},
/**
* 接收服务器推送的信息
* @param msgEvent
*/
onMessage(msgEvent) {
//收到服务器信息,心跳重置并发送
this.startHeartbeat()
const text = msgEvent.data
if (text.indexOf('pong') > 0) {
return
}
this.$notify.warning({
title: '消息提醒',
dangerouslyUseHTMLString: true,
message: text + '请及时处理',
offset: 60
})
},
/**
* 数据发送
* @param msg
*/
send(msg) {
//数据发送
this.webSocket.send(msg)
}
}
}
</script>