Vue3_开启全局websocket

1、封装websocket

新建文件夹"socket.ts",路径:"@/utils/socket"

javascript 复制代码
export default (onMessage: Function) => {
  let socketUrl = 'ws://171.29.8.218:8080/ems/ws/screen' //socket请求地址
  let socket: WebSocket
  let lockReconnect = false
  let timer: ReturnType<typeof setTimeout>
  const createSocket = () => {
    try {
      socket = new WebSocket(socketUrl)
      init()
    } catch (e) {
      console.log('catch' + e)
      reconnect()
    }
  }
  const reconnect = () => {
    if (lockReconnect) return
    lockReconnect = true
    clearTimeout(timer)
    timer = setTimeout(() => {
      createSocket()
    }, 4000)
  }

  const init = () => {
    socket.onopen = function (event) {
      console.log('WebSocket:已连接')
      //心跳检测重置
      heartCheck.reset().start()
    }

    //接收到消息的回调方法
    socket.onmessage = function (event) {
      console.log('WebSocket:收到一条消息', event.data)
      const isHeart = /pong/.test(event.data)
      if (onMessage && !isHeart) {
        //触发自定义onMessage
        onMessage.call(null, event)
      }
      heartCheck.reset().start()
    }

    //连接发生错误的回调方法
    socket.onerror = function (event) {
      console.log('WebSocket:发生错误')
      reconnect()
    }

    //连接关闭的回调方法
    socket.onclose = function (event) {
      console.log('WebSocket:已关闭')
      heartCheck.reset() //心跳检测
      reconnect()
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常
    window.onbeforeunload = function () {
      socket.close()
    }
  }

  var heartCheck = {
    timeout: 8000,
    timeoutObj: setTimeout(() => {}),
    serverTimeoutObj: setInterval(() => {}),
    reset: function () {
      clearTimeout(this.timeoutObj)
      clearTimeout(this.serverTimeoutObj)
      return this
    },
    start: function () {
      var self = this
      clearTimeout(this.timeoutObj)
      clearTimeout(this.serverTimeoutObj)
      this.timeoutObj = setTimeout(function () {
        //这里发送一个心跳,后端收到后,返回一个心跳消息,
        //onmessage拿到返回的心跳就说明连接正常
        socket.send(
          JSON.stringify({
            action: 'ping'
          })
        )
        self.serverTimeoutObj = setTimeout(function () {
          //如果超过一定时间还没重置,说明后端主动断开了(因此timeout设定时间要比后端返回socket间隔时间长,否则会判定后端主动断开)
          console.log('关闭服务')
          socket.close() //如果onclose会执行reconnect,我们执行 websocket.close()就行了.如果直接执行 reconnect 会触发onclose导致重连两次
        }, self.timeout)
      }, this.timeout)
    }
  }
  createSocket()
}

2、全局注册

在文件夹"main.ts"中

javascript 复制代码
import Websocket from "./utils/socket"
const onMessageList: Array<Function> = []; // 声明一个全局变量来收集onMessage列表,因为在不同的页面可能会有不同的处理
app.provide("onMessageList", onMessageList); // 全局注入
const onMessage = (event: any) => {
	// 遍历onMessage集合并触发
    onMessageList.forEach(f => {
        f.call(null, event);
    })
}
Websocket(onMessage); // 启动websocket

3、页面使用

javascript 复制代码
import { inject } from "vue";
const onMessageList = inject("onMessageList"); // 接收注入
const socketMessage = (res) => {
    const data = JSON.parse(res.data); // 获取数据
};
onMessageList.push(socketMessage); // 将自定义处理事件插入onMessge集合
相关推荐
mengge.cloud5 小时前
0909华为云计算类综合服务小白实验教程
linux·运维·服务器·网络·华为云·云计算
Zenova EdgeOS6 小时前
C++ 工业边缘 libcurl HTTP 客户端实战
开发语言·c++·网络协议·边缘计算
时空节拍AI数字人6 小时前
AI 数字人为什么需要“3D”?2D 不够用吗
人工智能·网络协议·tcp/ip·3d·信息可视化
制冷技术咨询与服务7 小时前
某纯电牵引车整车CAN网络
网络·汽车·can·某纯电牵引车整车can网络
zhengqweasd7 小时前
Linux网络(一):服务器数据包从网卡到应用程序,完整收包流程详解
linux·服务器·网络
小白羊丨8 小时前
HTTP/2 如何缓解 HTTP/1.1 阻塞;长连接对 Nginx 有什么影响?
网络协议·nginx·http
脚踏实地,坚持不懈!8 小时前
Linux 6.18.7 内存分配与回收 —— 代码梳理
linux·运维·网络
云边云科技_云网融合9 小时前
零售餐饮门店网络搭建:POS 交易稳定保障、IoT 设备联网运维、门店带宽优化、多终端并发适配
网络·物联网·零售
luj_176811 小时前
一线一区一变破解人盯人防守密码
开发语言·网络·c++·经验分享·算法
我的小卷呀11 小时前
Linux ip 命令底层逻辑与实战指南
linux·运维·c语言·网络协议·tcp/ip·网络安全