vue3.0中使用websocket,封裝到公共方法的實(shí)現(xiàn)
使用websocket,封裝到公共方法
首先創(chuàng)建一個(gè)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 // 當(dāng)前用戶信息,后臺(tái)配置 const token = store.state.users.authorization // 獲取驗(yàn)證信息,后臺(tái)配置 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}`, // 開啟標(biāo)識(shí) socket_open: false, // 心跳timer hearbeat_timer: null, // 心跳發(fā)送頻率 hearbeat_interval: 45000, // 是否自動(dòng)重連 is_reonnect: true, // 重連次數(shù) reconnect_count: 3, // 已發(fā)起重連次數(shù) reconnect_current: 1, // 網(wǎng)絡(luò)錯(cuò)誤提示此時(shí) ronnect_number: 0, // 重連timer reconnect_timer: null, // 重連頻率 reconnect_interval: 5000, init: (receiveMessage: Function | null) => { if (!('WebSocket' in window)) { ElMessage.warning('瀏覽器不支持WebSocket') return null } // 已經(jīng)創(chuàng)建過(guò)連接不再重復(fù)創(chuàng)建 // 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(() => { // 超過(guò)重連次數(shù) if (socket.reconnect_current > socket.reconnect_count) { clearTimeout(socket.reconnect_timer) socket.is_reonnect = false return } // 記錄重連次數(shù) socket.reconnect_current++ socket.reconnect() }, socket.reconnect_interval) } } // 連接成功 socket.websocket.onopen = function() { socket.socket_open = true socket.is_reonnect = true // 開啟心跳 // socket.heartbeat() } // 連接發(fā)生錯(cuò)誤 socket.websocket.onerror = function() {} }, send: (data, callback = null) => { // 開啟狀態(tài)直接發(fā)送 if (socket.websocket.readyState === socket.websocket.OPEN) { socket.websocket.send(JSON.stringify(data)) if (callback) { callback() } // 正在開啟狀態(tài),則等待1s后重新調(diào)用 } 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)
在這里 我們?yōu)閣ebsocket的onmessage方法傳入了一個(gè)函數(shù)作為參數(shù),這樣的話我們?cè)诮M件里面實(shí)現(xiàn)一個(gè)消息處理的方法
// 消息接收 receiveMessage(message: any) { const param = JSON.parse(Base64.decode(JSON.parse(message.data).data)) // 處理 賦值問(wèn)題 const params = JSON.parse(JSON.stringify(param)) if (params) { switch (params.message) { case 'scheduleListFeedBack': break case 'onMessage': // 地磁獲取消息列表 正則替換給過(guò)來(lái)的編碼 break } } },
這樣在onmessage里面的消息內(nèi)容,我們可以通過(guò)方法傳遞回來(lái),就可以在頁(yè)面里面使用,其中的scheduleListFeedBack、onMessage是和后端定義的websocket的特定消息響應(yīng)類型標(biāo)識(shí),可以拿到我們所需要的消息內(nèi)容,進(jìn)行邏輯處理。
這個(gè)方法是在socket.ts里面預(yù)先定義好的
socket.websocket.onmessage = (e: any) => { if (receiveMessage) { receiveMessage(e) } }
vue中封裝websocket問(wèn)題
每個(gè)組件頁(yè)面都用到websocket,可以講websocket封裝起來(lái),用到的組件頁(yè)面一調(diào)用就好。
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 ? //存儲(chǔ)回調(diào)函數(shù) ? callBackMapping = {} ? //標(biāo)識(shí)是否連接成功 ? connected = false ? //記錄重試的次數(shù) ? sendRetryCount = 0 ? //記錄重新連接的次數(shù) ? reconnectCount = 0 ? connect () { ? ? if (!window.WebSocket) { ? ? ? return console.log("您的瀏覽器不支持websocket!") ? ? } ? ? this.ws = new WebSocket('ws://192.168.0.88:8088') ? ? //連接服務(wù)端成功事件 ? ? this.ws.onopen = ()=> { ? ? ? console.log("連接服務(wù)端成功") ? ? ? this.connected = true ? ? ? this.reconnectCount = 0 ? ? } ? ? //連接服務(wù)端失敗事件 ? ? this.ws.onclose = ()=> { ? ? ? console.log("連接服務(wù)端失敗") ? ? ? this.connected = false ? ? ? this.reconnectCount++ ? ? ? setTimeout(()=>{ ? ? ? ? this.connect() ? ? ? },this.reconnectCount*500) ? ? } ? ? //從服務(wù)端獲取數(shù)據(jù) ? ? this.ws.onmessage = (msg)=> { ? ? ? console.log("從服務(wù)端獲取到的數(shù)據(jù)" + 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) ? ? ? ? } ? ? ? } ? ? } ? } ? //回調(diào)函數(shù)的注冊(cè) ? registerCallBack (socketType, callBack) { ? ? this.callBackMapping[socketType] = callBack ? } ? //取消回調(diào)函數(shù) ? 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.在組件里調(diào)用$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 ? ? ? ? ? } ? ? ? ? }) ? ? ? }, ? ? }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié))
這篇文章主要介紹了ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07在Vue中實(shí)現(xiàn)Excel導(dǎo)出功能(數(shù)據(jù)導(dǎo)出)
本文分享了如何在前端導(dǎo)出Excel文件,強(qiáng)調(diào)了前端導(dǎo)出的即時(shí)性、便捷性、靈活性和定制化優(yōu)勢(shì),以及減輕后端服務(wù)器負(fù)擔(dān)的特點(diǎn),詳細(xì)介紹了ExcelJS和FileSaver.js兩個(gè)工具庫(kù)的使用方法和主要功能,最后通過(guò)Vue實(shí)現(xiàn)了Excel的導(dǎo)出功能2024-10-10vue中使用jquery滑動(dòng)到頁(yè)面底部的實(shí)現(xiàn)方式
這篇文章主要介紹了vue中使用jquery滑動(dòng)到頁(yè)面底部的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法詳解
這篇文章主要介紹了vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法,結(jié)合實(shí)例形式分析了vue實(shí)現(xiàn)消息通知組件的具體原理、實(shí)現(xiàn)步驟、與相關(guān)操作技巧,需要的朋友可以參考下2020-03-03vue+vuex+axios實(shí)現(xiàn)登錄、注冊(cè)頁(yè)權(quán)限攔截
下面小編就為大家分享一篇vue+vuex+axios實(shí)現(xiàn)登錄、注冊(cè)頁(yè)權(quán)限攔截,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03undefined是否會(huì)變?yōu)閚ull原理解析
這篇文章主要為大家介紹了undefined是否會(huì)變?yōu)閚ull原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02vue打包靜態(tài)資源后顯示空白及static文件路徑報(bào)錯(cuò)的解決
這篇文章主要介紹了vue打包靜態(tài)資源后顯示空白及static文件路徑報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09