vue3.0中使用websocket,封裝到公共方法的實現(xiàn)
使用websocket,封裝到公共方法
首先創(chuàng)建一個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)前用戶信息,后臺配置
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}`,
// 開啟標(biāo)識
socket_open: false,
// 心跳timer
hearbeat_timer: null,
// 心跳發(fā)送頻率
hearbeat_interval: 45000,
// 是否自動重連
is_reonnect: true,
// 重連次數(shù)
reconnect_count: 3,
// 已發(fā)起重連次數(shù)
reconnect_current: 1,
// 網(wǎng)絡(luò)錯誤提示此時
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)建過連接不再重復(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(() => {
// 超過重連次數(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ā)生錯誤
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方法傳入了一個函數(shù)作為參數(shù),這樣的話我們在組件里面實現(xiàn)一個消息處理的方法
// 消息接收
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里面的消息內(nèi)容,我們可以通過方法傳遞回來,就可以在頁面里面使用,其中的scheduleListFeedBack、onMessage是和后端定義的websocket的特定消息響應(yīng)類型標(biāo)識,可以拿到我們所需要的消息內(nèi)容,進(jìn)行邏輯處理。
這個方法是在socket.ts里面預(yù)先定義好的
socket.websocket.onmessage = (e: any) => {
if (receiveMessage) {
receiveMessage(e)
}
}vue中封裝websocket問題
每個組件頁面都用到websocket,可以講websocket封裝起來,用到的組件頁面一調(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
? //存儲回調(diào)函數(shù)
? callBackMapping = {}
? //標(biāo)識是否連接成功
? 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ù)的注冊
? 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
? ? ? ? ? }
? ? ? ? })
? ? ? },
? ? }以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié))
這篇文章主要介紹了ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
在Vue中實現(xiàn)Excel導(dǎo)出功能(數(shù)據(jù)導(dǎo)出)
本文分享了如何在前端導(dǎo)出Excel文件,強調(diào)了前端導(dǎo)出的即時性、便捷性、靈活性和定制化優(yōu)勢,以及減輕后端服務(wù)器負(fù)擔(dān)的特點,詳細(xì)介紹了ExcelJS和FileSaver.js兩個工具庫的使用方法和主要功能,最后通過Vue實現(xiàn)了Excel的導(dǎo)出功能2024-10-10
vue中使用jquery滑動到頁面底部的實現(xiàn)方式
這篇文章主要介紹了vue中使用jquery滑動到頁面底部的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
vue+vuex+axios實現(xiàn)登錄、注冊頁權(quán)限攔截
下面小編就為大家分享一篇vue+vuex+axios實現(xiàn)登錄、注冊頁權(quán)限攔截,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
vue打包靜態(tài)資源后顯示空白及static文件路徑報錯的解決
這篇文章主要介紹了vue打包靜態(tài)資源后顯示空白及static文件路徑報錯的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09

