webScoket可以实时获取数据,做到实时渲染的效果,但ws一直连接着还好,万一网络波动,断了呢。。。。
那只能刷新页面,重新连接,但又不晓得啥时候断了,这时候就要用到心跳机制,对ws进行监视
// WebSocket连接地址 const wsUrl = ref('') // Ws实例 const ws = ref()
onMounted( () => { getId() // 获取用户id,利用id进行ws链接,否则会出现多用户打开断的情况。需要后端处理, })
const getId = () => { wsUrl.value = `${import.meta.env.VITE_WS}/processLog/socket/${userInfo.value.id}` // 这里在env.pro和env.dev里设置下VITE_WS变量(不要带引号),最后面是拿用户的id ws_create(wsUrl.value) }
// 创建WebSocket function ws_create(url: string) { try { // 判断是否支持 WebSocket if ('WebSocket' in window) { // 连接WebSocket ws.value = new WebSocket(url) // 初始化WebSocket事件(WebSocket对象, WebSocket连接地址) ws_event(ws.value, url) } } catch (e) { // 重新连接WebSocket ws_recontent(url) console.log('重新连接') } }
// WebSocket 事件创建 function ws_event(ws: any, url: string) { ws.onopen = function (event: any) { // 心跳检测重置 ws_heartCheck.reset().start() console.log('WebSocket已连接') } ws.onclose = function (event: any) { // 重新连接WebSocket ws_recontent(url) console.log('WebSocket连接已关闭') } ws.onerror = function (event: any) { // 重新连接WebSocket ws_recontent(url) console.log('WebSocket错误:', event) } ws.onmessage = function (event: any) { // 只要有数据,那就说明连接正常 ws_heartCheck.reset().start() // 处理数据,只处理非心跳检测的数据 const result = JSON.parse(event.data) console.log(result, 'result') // 处理数据逻辑 } }
// 重新连接websocker(WebSocket连接地址) function ws_recontent(url) { // 延迟避免请求过多 setTimeout(() => { ws_create(wsUrl.value) }, 3000) }
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,这样服务端会抛异常。 window.onbeforeunload = function () { ws.value.close() }
// 核心逻辑 根据后端在规定时间内返回的心跳数据进行判断。比如后端5s返回一次心跳数据,定时器就设在5s左右,如果有数据返回,就直接进到ws.onMessage里了,如果没有,超过了定时器的时间,就会close这次链接,然后在规定的几秒后进行重新连接,也就是ws_recontent方法,时间就是3s
// 10秒一次心跳 const timeOut = ref(10000) // 执行心跳的定时器 const timeoutObj = ref() // 服务器超时定时器 const serverTimeoutObj = ref() // WebSocket心跳检测 var ws_heartCheck = { reset() { // 重置方法 clearTimeout(timeoutObj.value) clearTimeout(serverTimeoutObj.value) return this }, start() { // 启动方法 timeoutObj.value = setTimeout(() => { // 这里发送一个心跳信息,后端收到后,返回一个消息,在onmessage拿到返回的心跳(信息)就说明连接正常 // ws.value.send('check') // 如果超过一定时间还没重置,说明后端主动断开了 serverTimeoutObj.value = setTimeout(() => { // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 ws.value.close() }, timeOut.value) }, timeOut.value) }, }
标签:WebSocket,value,event,ws,心跳,机制,重连,webScoket,连接 From: https://www.cnblogs.com/alannero/p/17695551.html