websocket在vue3+ts中的封装及使用方法

wensocket.ts文件中

// src/utils/websocket.ts
import { ref, onUnmounted } from 'vue';

interface WebSocketOptions {
    url: string;
    protocols?: string | string[];
    reconnectTimeout?: number;
}

class WebSocketService {
    private ws: WebSocket | null = null;
    private callbacks: { [key: string]: Function[] } = {};
    private reconnectTimeoutMs: number = 5000; // 默认5秒重连间隔

    constructor(private options: WebSocketOptions) {}

    public open(): void {
        this.ws = new WebSocket(this.options.url, this.options.protocols)
        this.ws.addEventListener('open', this.handleOpen);
        this.ws.addEventListener('message', this.handleMessage);
        this.ws.addEventListener('error', this.handleError);
        this.ws.addEventListener('close', this.handleClose);
    }

    public close(isActiveClose = false): void {
        if (this.ws) {
            this.ws.close();
            if (!isActiveClose) {
                setTimeout(() => this.reconnect(), this.reconnectTimeoutMs);
            }
        }
    }

    public reconnect(): void {
        this.open();
    }

    public on(event: 'message', callback: (data: any) => void): void;
    public on(event: 'open' | 'error' | 'close', callback: () => void): void;
    public on(event: string, callback: (...args: any[]) => void): void {
        if (!this.callbacks[event]) {
            this.callbacks[event] = [];
        }
        this.callbacks[event].push(callback);
    }

    private handleOpen = (): void => {
        console.log('WebSocket连接已建立');
        if (this.callbacks.open) {
            this.callbacks.open.forEach((cb) => cb());
        }
    };

    private handleMessage = (event: MessageEvent): void => {
        const data = JSON.parse(event.data);
        console.log('WebSocket接收到消息:', data);
        if (this.callbacks.message) {
            this.callbacks.message.forEach((cb) => cb(data));
        }
    };

    private handleError = (error: Event): void => {
        console.error('WebSocket错误:', error);
        if (this.callbacks.error) {
            this.callbacks.error.forEach((cb) => cb(error));
        }
    };

    private handleClose = (): void => {
        console.log('WebSocket连接已关闭');
        if (this.callbacks.close) {
            this.callbacks.close.forEach((cb) => cb());
            if (!this.options.reconnectTimeout) {
                this.reconnect();
            }
        }
    };

    public send(data: any): void {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(data));
        } else {
            console.warn('尝试发送消息时WebSocket未连接');
        }
    }
}

export default function useWebSocket(options: WebSocketOptions) {
    const wsService = new WebSocketService(options);

    onUnmounted(() => {
        wsService.close(true);
    });

    return {
        open: wsService.open.bind(wsService),
        close: wsService.close.bind(wsService),
        reconnect: wsService.reconnect.bind(wsService),
        on: wsService.on.bind(wsService),
        send: wsService.send.bind(wsService)
    };

使用

import useWebSocket from '@/utils/websocket';//引入websocket.ts文件

import config from '@/config' //引入公共配置文件

const wsOptions = {
  url: config.wbBaseURL,
};

const { open, close, reconnect, on, send } = useWebSocket(wsOptions);

onMounted(() => {
  open();//在onMounted钩子中调用open函数,链接websocket

  // 注册消息接收处理函数
  on('message', (data) => {
    receivedMessage = data;
    console.log(data)
  });
});

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值