vue封装使用公共组件(vue3.0中使用websocket,封装到公共方法的实现)
导读:使用websocket,封装到公共方法 首先创建一个socket.ts文件封装公共方法...
使用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
}
})
},
}
以上为个人经验 ,希望能给大家一个参考,也希望大家多多支持本站 。
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!