切换语言为:繁体

基于 Websocket 与 Pinia 封装一个全局长链接

  • 爱糖宝
  • 2024-09-26
  • 2044
  • 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.