一. 目标
先有实时数据需要展示. 由于设备量极大且要对设备参数实时记录展示.axios空轮询不太适合.
选择websocket长连接通讯.
使用pinia原因是pinia具备共享数据性质.可以作为消息队列缓存数据,降低渲染压力.同时方便多个页面或组件获取websocket数据
二. 前置环境
安装pinia
注册pinia不再详细叙述,自行看官方文档.
npm install pinia
- 1
三. websocket通用模板
笔者自行整合网络资源,写了一套较为通用的通信模板. 包含 消息队列缓存, 心跳检测, 断线重连.读者可以自行阅读以下代码调整到业务所需.同时也请大家捉虫,笔者会及时修改.
import {defineStore} from "pinia";
import {ref} from "vue";
// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useWebSocketStore = defineStore(''resource'', {
// 其他配置...
state: () => ({
// 这里是你的状态
socket: null,
messageQueue: [],
readyState: 0,
socketMessage:''1''
}),
getters: {
// 这里是你的 getters
SET_SOCKET: (state: any, socket: any) => {
state.socket = socket;
},
SET_SOCKET_MESSAGE: (state: any, socketMessage: any) => {
state.socketMessage = socketMessage;
}
},
actions: {
// 这里是你的 actions
connectWebSocket() {
const PING_INTERVAL = 5000; // 心跳间隔,单位为毫秒
const heartbeatMessage = {type:0, msg:"ping"}; // 心跳消息
const heartbeatMessage2 = {type:0, msg:"pong", data:[''在线设备'']}; // 心跳消息
const HOST_ADDRESS = ''ws://127.0.0.1:7531''
const socket = ref(new WebSocket(HOST_ADDRESS))
let checkTask = null
// 监听连接事件
socket.value.onopen = () => {
// 启动心跳检测 确保连接存活 客户端每隔5秒向服务端发送一次心跳消息
console.log(heartbeatMessage)
checkTask = setInterval(() => {
socket.value.send(JSON.stringify(heartbeatMessage))
}, PING_INTERVAL)
}
// 监听消息事件
socket.value.onmessage = (event) => {
console.log(event.data,"event2")
const message = JSON.parse(event.data)
if (message.type == WebSocket.CONNECTING) {
socket.value.send(JSON.stringify(heartbeatMessage2))
return
} else {
if(this.messageQueue.length > 2<<16) {
this.messageQueue = []
}
console.log(''WebSocket消息: '', message)
this.SET_SOCKET_MESSAGE(message)
}
}
// 监听关闭事件 断线重连
socket.value.onclose = () => {
if(this.socket.readyState === WebSocket.CLOSED) {
this.messageQueue.forEach((message) => {
this.sendMessage(message)
});
this.messageQueue = []
}
// 清除心跳计时器
checkTask && clearInterval(checkTask)
// 断线重连
setTimeout(() => {
this.connectWebSocket()
},3000)
}
// 连接错误
socket.value.onerror = (event) => {
console.log(''WebSocket error:'', event)
}
},
// 发送消息方法
sendMessage(message: string) {
this.socket.send(message)
}
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90