vue3+ts封装Websocket

Vue3中使用Websocket可以让我们轻松地实现实时数据传输。为了方便使用,我们可以封装一个好用的Websocket类。

安装依赖

首先我们需要安装 ws 库来处理Websocket连接,使用以下命令进行安装:

npm install ws --save

使用ts+vue3封装组件

javascript 复制代码
import { onUnmounted } from 'vue';

//设置
interface SocketOptions {
  //心跳间隔
  heartbeatInterval?: number;
  //超时重传
  reconnectInterval?: number;
  //最大重传次数
  maxReconnectAttempts?: number;
}

class Socket {
  //路径
  url: string;
  ws: WebSocket | null = null;
  opts: SocketOptions;
  //重传次数
  reconnectAttempts: number = 0;
  listeners: { [key: string]: Function[] } = {};
  //心跳间隔
  heartbeatInterval: number | null = null;
  //构造函数
  constructor(url: string, opts: SocketOptions = {}) {
    this.url = url;
    this.opts = {
      //心跳间隔
      heartbeatInterval: 30000,
      //超时重传
      reconnectInterval: 5000,
      //最大重传次数
      maxReconnectAttempts: 5,
      ...opts
    };

    this.init();
  }
  //初始化
  init() {
    this.ws = new WebSocket(this.url);
    this.ws.onopen = this.onOpen.bind(this);
    this.ws.onmessage = this.onMessage.bind(this);
    this.ws.onerror = this.onError.bind(this);
    this.ws.onclose = this.onClose.bind(this);
  }
  //打开
  onOpen(event: Event) {
    console.log('WebSocket opened:', event);
    this.reconnectAttempts = 0;
    this.startHeartbeat();
    this.emit('open', event);
  }
  //收到的WebSocket消息
  onMessage(event: MessageEvent) {
    // console.log('WebSocket message received:', event.data);
    this.emit('message', event.data);
  }
  //错误
  onError(event: Event) {
    console.error('WebSocket error:', event);
    this.emit('error', event);
  }
  //重连逻辑中,在连接失败后自动重新连接
  onClose(event: CloseEvent) {
    console.log('WebSocket closed:', event);
    this.stopHeartbeat();
    this.emit('close', event);
    //重连逻辑中,在连接失败后自动重新连接,但会限制重连的次数和每次重连之间的间隔时间
    if (this.opts.maxReconnectAttempts !== 0 && this.reconnectAttempts < this.opts.maxReconnectAttempts!) {
      setTimeout(() => {
        // console.log("我有错误了1111111111111111111111111111111111111");
        this.reconnectAttempts++;
        this.init();
      }, this.opts.reconnectInterval);
    }
  }
  //开始心跳检测
  startHeartbeat() {
    if (!this.opts.heartbeatInterval) return;

    this.heartbeatInterval = window.setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send('ping');
      }
    }, this.opts.heartbeatInterval);
  }
  //停止心跳检测
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }
  //发送消息
  send(data: string) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    } else {
      console.error('WebSocket is not open. Cannot send:', data);
    }
  }
  //事件监听器注册功能的实现
  on(event: string, callback: Function) {
    if (!this.listeners[event]) {
      this.listeners[event] = [];
    }
    this.listeners[event].push(callback);
  }
  //从事件监听器中移除
  off(event: string) {
    if (this.listeners[event]) {
      delete this.listeners[event];
    }
  }
  //在事件监听器中触发一个指定的事件
  emit(event: string, data: any) {
    this.listeners[event]?.forEach(callback => callback(data));
  }
}

export function useSocket(url: string, opts?: SocketOptions) {
  const socket = new Socket(url, opts);

  onUnmounted(() => {
    socket.off('open');
    socket.off('message');
    socket.off('error');
    socket.off('close');
    socket.ws?.close(); // 关闭WebSocket连接  
  });

  return {
    socket,
    send: socket.send.bind(socket),
    on: socket.on.bind(socket),
    off: socket.off.bind(socket)
  };
}

使用

javascript 复制代码
import { useSocket } from "../../utils/websocket";

const { socket, send, on, off } = useSocket(
  `ws://192.168.22.32:8000/v1/user/chats`
);

 on("close", () => console.log("Socket closed!"));
  //webSocket连接上服务器时
  on("open", event => {
    console.log("webSocket连接上服务器时", event);
  });
socket.on("message", data => {
console.log("Received data:", data); })


   send(xxxx);
相关推荐
_im.m.z4 小时前
【设计模式学习笔记】1. 设计模式概述
笔记·学习·设计模式
胡西风_foxww6 小时前
【ES6复习笔记】迭代器(10)
前端·笔记·迭代器·es6·iterator
左漫在成长7 小时前
王佩丰24节Excel学习笔记——第十九讲:Indirect函数
笔记·学习·excel
纪伊路上盛名在7 小时前
Max AI prompt1
笔记·学习·学习方法
Suwg2098 小时前
【MySQL】踩坑笔记——保存带有换行符等特殊字符的数据,需要进行转义保存
数据库·笔记·mysql
胡西风_foxww8 小时前
【ES6复习笔记】对象方法扩展(17)
前端·笔记·es6·对象·方法·扩展·对象方法扩展
左漫在成长8 小时前
王佩丰24节Excel学习笔记——第十八讲:Lookup和数组
笔记·学习·excel
代码小将9 小时前
PTA数据结构编程题7-1最大子列和问题
数据结构·c++·笔记·学习·算法
annesede9 小时前
计算机操作系统与安全复习笔记
笔记
滴_咕噜咕噜9 小时前
学习笔记 --C#基础其他知识点(持续更新)
笔记·学习·c#