切換語言為:簡體

基於 Websocket 與 Pinia 封裝一個全域性長連結

  • 爱糖宝
  • 2024-09-26
  • 2045
  • 0
  • 0

背景

本次專案為內嵌頁面,需要使用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({}))

結尾

程式碼比較簡單,如果有不對的地方,請指出,改正哈!!!

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.