背景
本次项目为内嵌页面,需要使用Websocket与unity交互,心想着在很多地方都用上了,业务也基本全部靠着websocket来交互,所以就打算写一个全局的,先在网上搜了一遍都不甚满意,还是自己封装一个吧,也比较简单,本章就当个分享记录吧!!!
准备
yarn add pinia # 或者使用 npm npm install pinia
Class Websocket
在我的utils文件夹中创建一个websocket.js
先封装一个可以局部使用的Websocket,里面的东西不是很多,因为我的业务与常见的有些不同,所以就展示一个基础的架子,可以根据你们的需要写入自己的逻辑!
里面的事件触发机制写了两套,分别适应不同的地方,一种是直接覆盖原函数,另一种是根据需要注册,按照自己的需求来,或者写一个自己喜欢的,删除另外的。
class BaseWebSocket { constructor(url) { this.url = url; this.websocket = null; this.isConnected = false; this.listeners = [] } connect() { if (this.isConnected) { return } this.websocket = new WebSocket(this.url); this.websocket.onopen = () => { this.isConnected = true; console.log(`${this.url} 连接成功`); }; this.websocket.onmessage = (event) => { // console.log('Received:', JSON.parse(event.data)); const data = JSON.parse(event.data); this.messageEvent(data) this.notifyListeners('message', data); } this.websocket.onerror = (error) => { console.error('WebSocket Error:', error); this.errorEvent(error) } this.websocket.onclose = (event) => { console.log('WebSocket close:', event); this.isConnected = false; this.closeEvent(event) } } /** * 消息事件 * */ messageEvent(event) { } /** * 错误事件 * */ errorEvent(error) { } /** * 关闭事件 * */ closeEvent(event) { } /** * 发消息 * */ sendMessage(data) { if (this.isConnected && this.websocket) { this.websocket.send(data); } else { console.error('WebSocket is not connected'); } } /** * 关闭ws * */ closeWebSocket() { this.websocket && this.websocket.close(); } /** * 心跳机制 * */ heartbeat() { // TODO... } /** * 自定义事件注册 * */ addMessageListener(listener) { this.listeners.push(listener); } /** * 通知到对应类型事件 * */ notifyListeners(eventType, data = null) { this.listeners.forEach(listener => { listener(eventType, data); }); } } export default BaseWebSocket
Pinia + websocket.js
useGetNuclearWsStore
仓库主要管理收到的数据
import {defineStore} from 'pinia' import {toRefs, reactive} from 'vue' import BaseWebSocket from '@/utils/websocket.js' const useGetNuclearWsStore = defineStore('getNuclear', () => { const state = reactive({ url: 'ws://127.0.0.1:8082/getNuclear', data: '', }) const eventFns = reactive({ messageHandle: () => { }, closeHandle: () => { }, errorHandle: () => { }, }) const websocket = new BaseWebSocket(state.url) websocket.connect() websocket.messageEvent = (data) => { state.data = data } const closeWebSocket = () => { websocket.closeWebSocket() } const sendMessage = (data) => { websocket.sendMessage(data) } websocket.addMessageListener((eventType, data) => { switch (eventType) { case 'message': eventFns.messageHandle(data) break } }) return { websocket, ...toRefs(state), ...toRefs(eventFns), closeWebSocket, sendMessage, } }) export default useGetNuclearWsStore
useSetNuclearWsStore
仓库主要管理发送的数据
当然以上两个都具备收发能力,只不过侧重点不同。
import {defineStore} from 'pinia' import {toRefs, reactive} from 'vue' import BaseWebSocket from '@/utils/websocket.js' const useSetNuclearWsStore = defineStore('setNuclear', () => { const state = reactive({ url: 'ws://127.0.0.1:8082/setNuclear', data: '', }) const eventFns = reactive({ messageHandle: () => { }, closeHandle: () => { }, errorHandle: () => { }, }) const websocket = new BaseWebSocket(state.url) websocket.connect() const closeWebSocket = () => { websocket.closeWebSocket() } const sendMessage = (data) => { websocket.sendMessage(data) } return { websocket, ...toRefs(state), ...toRefs(eventFns), closeWebSocket, sendMessage, } }) export default useSetNuclearWsStore
使用
import useSetNuclearWsStore from "@/stores/useSetNuclearWsStore.js"; import useGetNuclearWsStore from "@/stores/useGetNuclearWsStore.js"; const getNuclearWsStore = useGetNuclearWsStore() getNuclearWsStore.messageHandle = (data)=>{ console.log(data) } const {sendMessage} = useSetNuclearWsStore() sendMessage(JSON.stringify({}))
结尾
代码比较简单,如果有不对的地方,请指出,改正哈!!!