新建webSocket.js文件
let ws = null // webSocket实例
const webSocketState = ref(false) //// webSocket的连接状态
const heartBeat = ref({
// // 心跳连接的时间设置
time: 5 * 1000, // 心跳时间间隔
timeout: 3 * 1000, // timeout:心跳超时间隔(!要少于心跳间隔)
reconnect: 10 * 1000 // 断线重连时间
})
let reconnectTimer = null // 断线重连定时器
const useWebSocket = () => {
// 关闭连接
const OnClose = () => {
ws.close() // 关闭webSocket
webSocketState.value = false // 设置webSocket状态为关闭
heartBeat.value.time = null // 清空心跳时间 停止心跳
if (reconnectTimer) {
//关闭重连定时器
clearTimeout(reconnectTimer)
}
}
// 开启连接
const OnLocation = () => {
heartBeat.value.time = 5 * 1000 //因为关闭时会置空,所以在这重新初始化一下
connectWebSocket() //建立连接
}
// 建立连接
const connectWebSocket = () => {
let url = `http://semiauto.aarobot.com/v1.0/message`
//这里连接地址根据自己的业务设置,注意:如果连接本地进行调试的时候,要用'ws',如:“ws://192.168.2.15:8080/msg”
ws = new WebSocket(url)
init() //初始化
}
// 初始化
const init = () => {
ws.addEventListener('open', () => {
webSocketState.value = true //socket状态设置为连接,做为后面的断线重连的拦截器
console.log('开启')
heartBeat.value && heartBeat.value.time ? startHeartBeat(heartBeat.value.time) : '' // 是否启动心跳机制
})
ws.addEventListener('message', (e) => {
webSocketState.value = true
console.log(JSON.parse(e.data), '信息')
})
ws.addEventListener('close', (e) => {
webSocketState.value = false // socket状态设置为断线
console.log('断开了连接', e)
})
ws.addEventListener('error', (e) => {
webSocketState.value = false // socket状态设置为断线
reconnectWebSocket() // 重连
console.log('连接发生了错误', e)
})
}
// 心跳 time:心跳时间间隔
const startHeartBeat = (time) => {
setTimeout(() => {
//这里设置这是你要发送的内容 如果后端没有设置心跳,则不需要发送
// let data = {} //data 发送给服务端的数据
// ws.send(JSON.stringify(data)) //发送数据
waitingServer()
}, time)
}
// 延时等待服务端响应,通过webSocketState判断是否连线成功
const waitingServer = () => {
webSocketState.value = false
setTimeout(() => {
if (webSocketState.value) {
startHeartBeat(heartBeat.value.time)
return
}
console.log('心跳无响应,已断线')
try {
ws.close()
} catch (e) {
console.log('连接已关闭,无需关闭')
}
reconnectWebSocket() //非主动关闭导致,触发重连
}, heartBeat.value.timeout)
}
// 重连操作
const reconnectWebSocket = () => {
reconnectTimer = setTimeout(() => {
console.log('重连中...')
reconnectWs()
}, heartBeat.value.reconnect)
}
const reconnectWs = () => {
if (!heartBeat.value.time) return //如果主动关闭,则防止重连
if (!ws) {
// 第一次执行,初始化
connectWebSocket()
}
if (ws && reconnectTimer) {
// 防止多个websocket同时执行
clearTimeout(reconnectTimer)
ws.reconnectTimer = null
connectWebSocket()
}
}
return {
OnLocation,
OnClose
}
}
export default useWebSocket
由于个人项目是全局所以将放到app.vue里
import useWebSocket from '@/utils/webSocket'
const { OnLocation, OnClose } = useWebSocket()
//连接
OnLocation()
//关闭连接
OnClose()