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);
相关推荐
LN花开富贵1 小时前
stm32g431rbt6芯片中VREF+是什么?在电路中怎么设计?
笔记·stm32·单片机·嵌入式硬件·学习
qq21084629531 小时前
【stm32笔记】使用rtt-studio与stm32CubeMx联合创建项目
笔记·stm32·嵌入式硬件
liangbm32 小时前
MATLAB系列07:输入/输入函数
开发语言·数据库·笔记·matlab·函数·自定义函数·matlab函数
酒饮微醉-3 小时前
论文阅读--Planning-oriented Autonomous Driving(一)
论文阅读·笔记·学习·自动驾驶
GoppViper3 小时前
golang学习笔记28——golang中实现多态与面向对象
笔记·后端·学习·golang·多态·面向对象
Red Red4 小时前
GEO数据库提取疾病样本和正常样本|GEO数据库区分疾病和正常样本|直接用|生物信息|生信
开发语言·数据库·笔记·学习·r语言·c#·生物信息
视觉小鸟4 小时前
【java面试每日五题之基础篇一】(仅个人理解)
java·笔记·面试
handsome2139 小时前
WSL中使用GPU加速AMBER MD--测试
笔记·学习
吃着火锅x唱着歌12 小时前
Go语言设计与实现 学习笔记 第七章 内存管理(1)
笔记·学习·golang
~在杰难逃~13 小时前
关于订单信息的Excel数据分析报告
笔记·数据分析·excel·数据分析报告