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);
相关推荐
LK_075 分钟前
【Open3D】Ch.3:顶点法向量估计 | Python
开发语言·笔记·python
li星野16 分钟前
打工人日报#20251011
笔记·程序人生·fpga开发·学习方法
摇滚侠19 分钟前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
QT 小鲜肉20 分钟前
【个人成长笔记】在Ubuntu中的Linux系统安装 anaconda 及其相关终端命令行
linux·笔记·深度学习·学习·ubuntu·学习方法
QT 小鲜肉22 分钟前
【个人成长笔记】在Ubuntu中的Linux系统安装实验室WIFI驱动安装(Driver for Linux RTL8188GU)
linux·笔记·学习·ubuntu·学习方法
急急黄豆39 分钟前
MADDPG学习笔记
笔记·学习
Chloeis Syntax1 小时前
栈和队列笔记2025-10-12
java·数据结构·笔记·
QZ_orz_freedom2 小时前
学习笔记--文件上传
java·笔记·学习
摇滚侠2 小时前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记
爱吃甜品的糯米团子3 小时前
Linux 学习笔记之 VI 编辑器与文件查找技巧
linux·笔记·学习