vue3+ts+pinia整合websocket

文章目录

    • [一. 目标](#一. 目标)
    • [二. 前置环境](#二. 前置环境)
    • [三. websocket通用模板](#三. websocket通用模板)

一. 目标

先有实时数据需要展示. 由于设备量极大且要对设备参数实时记录展示.axios空轮询不太适合.

选择websocket长连接通讯.

使用pinia原因是pinia具备共享数据性质.可以作为消息队列缓存数据,降低渲染压力.同时方便多个页面或组件获取websocket数据


二. 前置环境

安装pinia

注册pinia不再详细叙述,自行看官方文档.

复制代码
npm install pinia    

三. websocket通用模板

笔者自行整合网络资源,写了一套较为通用的通信模板. 包含 消息队列缓存, 心跳检测, 断线重连.读者可以自行阅读以下代码调整到业务所需.同时也请大家捉虫,笔者会及时修改.

typescript 复制代码
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)
        }
        
    }

})
相关推荐
2501_937860942 小时前
中篇:TCP 为什么可靠又高效?滑动窗口、流量控制、拥塞控制与粘包全解析
服务器·网络·tcp/ip
刚及格的陆拾伍3 小时前
Wi-Fi核心知识精要:从频段到帧结构全解析
网络·物联网·网络协议·信息与通信·iot
xiaoye-duck3 小时前
《Linux 网络编程》深入理解 IO 多路复用:select 函数详解与 Echo 服务实战
linux·网络
xfan_me4 小时前
SSL 证书落地应用与网站安全加固
网络协议·安全·ssl
SDWAN_Cheap4 小时前
TCP滑动窗口与拥塞控制是什么?从流量控制到网络稳定性的完整解析
网络·tcp/ip·php
广东融科数据服务有限公司4 小时前
无网络仓储库房安防监控改造落地案例|离线闭环存储 + 4G 低功耗远程适配实战优化
网络·仓储改造
YumiProxy4 小时前
动态IP冲突排查实战:从ARP检测到DHCP地址池的完整链路
服务器·网络·网络协议·tcp/ip·ip
Dynadot_tech4 小时前
域名投资中的域名管理策略
网络·域名·域名注册·dynadot·域名管理
CHENKONG_CK5 小时前
RFID 赋能汽车零部件涂装产线,构建全流程数字化追溯体系
网络·人工智能·单片机·网络协议·tcp/ip·汽车
优化Henry5 小时前
BBU与RRU光链路详解:从双纤一收一发到单纤双向
网络·笔记·学习·5g·tdd