vue3.0中使用websocket,封装到公共方法的实现

Liana ·
更新时间:2024-11-10
· 200 次阅读

目录

使用websocket,封装到公共方法

vue中封装websocket问题 

1.在untils文件夹下新建socket_service.js

2.在main.js里引用

2.在组件里调用$socket

使用websocket,封装到公共方法

首先创建一个socket.ts文件封装公共方法

/* * @Descripttion: 封装socket方法 * @version: * @Date: 2021-08-06 11:14:39 * @LastEditTime: 2021-10-26 14:06:34 */ import i18n from '@/locales' import store from '@/store' import { ElMessage } from 'element-plus' import { Base64 } from 'js-base64' const language = store.state.users.language // 当前用户信息,后台配置 const token = store.state.users.authorization // 获取验证信息,后台配置 interface socket { websocket: any connectURL: string socket_open: boolean hearbeat_timer: any hearbeat_interval: number is_reonnect: boolean reconnect_count: number reconnect_current: number ronnect_number: number reconnect_timer: any reconnect_interval: number init: (receiveMessage: Function | null) => any receive: (message: any) => void heartbeat: () => void send: (data: any, callback?: any) => void close: () => void reconnect: () => void } const socket: socket = { websocket: null, connectURL: `${process.env.VUE_APP_SOCEKT_URL}/websocket/v1/${language}/${token}`, // 开启标识 socket_open: false, // 心跳timer hearbeat_timer: null, // 心跳发送频率 hearbeat_interval: 45000, // 是否自动重连 is_reonnect: true, // 重连次数 reconnect_count: 3, // 已发起重连次数 reconnect_current: 1, // 网络错误提示此时 ronnect_number: 0, // 重连timer reconnect_timer: null, // 重连频率 reconnect_interval: 5000, init: (receiveMessage: Function | null) => { if (!('WebSocket' in window)) { ElMessage.warning('浏览器不支持WebSocket') return null } // 已经创建过连接不再重复创建 // if (socket.websocket) { // return socket.websocket // } socket.websocket = new WebSocket(socket.connectURL) socket.websocket.onmessage = (e: any) => { if (receiveMessage) { receiveMessage(e) } } socket.websocket.onclose = (e: any) => { clearInterval(socket.hearbeat_interval) socket.socket_open = false // 需要重新连接 if (socket.is_reonnect) { socket.reconnect_timer = setTimeout(() => { // 超过重连次数 if (socket.reconnect_current > socket.reconnect_count) { clearTimeout(socket.reconnect_timer) socket.is_reonnect = false return } // 记录重连次数 socket.reconnect_current++ socket.reconnect() }, socket.reconnect_interval) } } // 连接成功 socket.websocket.onopen = function() { socket.socket_open = true socket.is_reonnect = true // 开启心跳 // socket.heartbeat() } // 连接发生错误 socket.websocket.onerror = function() {} }, send: (data, callback = null) => { // 开启状态直接发送 if (socket.websocket.readyState === socket.websocket.OPEN) { socket.websocket.send(JSON.stringify(data)) if (callback) { callback() } // 正在开启状态,则等待1s后重新调用 } else { clearInterval(socket.hearbeat_timer) if (socket.ronnect_number < 1) { ElMessage({ type: 'error', message: i18n.global.t('chat.unopen'), duration: 0, }) } socket.ronnect_number++ } }, receive: (message: any) => { let params = Base64.decode(JSON.parse(message.data).data) params = JSON.parse(params) return params }, heartbeat: () => { if (socket.hearbeat_timer) { clearInterval(socket.hearbeat_timer) } socket.hearbeat_timer = setInterval(() => { let data = { languageId: store.state.users.language, authToken: store.state.users.authorization, content: 'ping', } var sendDara = { encryption_type: 'base64', data: Base64.encode(JSON.stringify(data)), } socket.send(sendDara) }, socket.hearbeat_interval) }, close: () => { clearInterval(socket.hearbeat_interval) socket.is_reonnect = false socket.websocket.close() }, /** * 重新连接 */ reconnect: () => { if (socket.websocket && !socket.is_reonnect) { socket.close() } socket.init(null) }, } export default socket

然后在聊天组件中引入

import socket from '@/utils/socket'

在挂载的生命周期放方法里面初始化socket

socket.init(methods.receiveMessage)

在这里 我们为websocket的onmessage方法传入了一个函数作为参数,这样的话我们在组件里面实现一个消息处理的方法

// 消息接收 receiveMessage(message: any) { const param = JSON.parse(Base64.decode(JSON.parse(message.data).data)) // 处理 赋值问题 const params = JSON.parse(JSON.stringify(param)) if (params) { switch (params.message) { case 'scheduleListFeedBack': break case 'onMessage': // 地磁获取消息列表 正则替换给过来的编码 break } } },

这样在onmessage里面的消息内容,我们可以通过方法传递回来,就可以在页面里面使用,其中的scheduleListFeedBack、onMessage是和后端定义的websocket的特定消息响应类型标识,可以拿到我们所需要的消息内容,进行逻辑处理。

这个方法是在socket.ts里面预先定义好的

socket.websocket.onmessage = (e: any) => { if (receiveMessage) { receiveMessage(e) } } vue中封装websocket问题 

每个组件页面都用到websocket,可以讲websocket封装起来,用到的组件页面一调用就好。

1.在untils文件夹下新建socket_service.js export default class SocketService {   static instance = null   static get Instance () {     if (!this.instance) {       this.instance = new SocketService()     }     return this.instance   }   ws = null   //存储回调函数   callBackMapping = {}   //标识是否连接成功   connected = false   //记录重试的次数   sendRetryCount = 0   //记录重新连接的次数   reconnectCount = 0   connect () {     if (!window.WebSocket) {       return console.log("您的浏览器不支持websocket!")     }     this.ws = new WebSocket('ws://192.168.0.88:8088')     //连接服务端成功事件     this.ws.onopen = ()=> {       console.log("连接服务端成功")       this.connected = true       this.reconnectCount = 0     }     //连接服务端失败事件     this.ws.onclose = ()=> {       console.log("连接服务端失败")       this.connected = false       this.reconnectCount++       setTimeout(()=>{         this.connect()       },this.reconnectCount*500)     }     //从服务端获取数据     this.ws.onmessage = (msg)=> {       console.log("从服务端获取到的数据" + msg.data)       const recvData = JSON.parse(msg.data)       const socketType = recvData.socketType       if (this.callBackMapping[socketType]) {         const action = recvData.action         if (action === 'getData') {           const realData = JSON.parse(recvData.data)           this.callBackMapping[socketType].call(this, realData)         }       }     }   }   //回调函数的注册   registerCallBack (socketType, callBack) {     this.callBackMapping[socketType] = callBack   }   //取消回调函数   unRegisterCallBack (socketType) {     this.callBackMapping[socketType] = null   }   send(data) {     if (this.connected) {       this.sendRetryCount = 0       this.ws.send(JSON.stringify(data))     } else {       this.sendRetryCount++       setTimeout(()=>{         this.ws.send(JSON.stringify(data))       },this.sendRetryCount*500)     }   }  } 2.在main.js里引用 import SocketService from '@/utils/socket_service' SocketService.Instance.connect() Vue.prototype.$socket = SocketService.Instance Vue.prototype.wsPath = 'ws://192.168.0.88:8088/'     // websocket路径 2.在组件里调用$socket mounted() {      this.$socket.send({         action:'getData',         socketType:'productivity',         chartName:'product',         value:''       })     }, created() {       this.$socket.registerCallBack('productivity',this.getWsData)     }, destroyed() {      this.$socket.unRegisterCallBack('productivity')     }, methods:{     getWsData (ret) {         console.log('websocket接收到的值', event.ret)         console.log(ret);         this.cdata.category.forEach(item => {           if (dataRec.materialClassifyName === item.materialClassifyName) {             item.rate = dataRec.rate           }         })       },     }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



VUE 方法 封装 websocket

需要 登录 后方可回复, 如果你还没有账号请 注册新账号