背景
本次專案為內嵌頁面,需要使用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({}))
結尾
程式碼比較簡單,如果有不對的地方,請指出,改正哈!!!