vue3中封装使用WebSocket

在vue3+ts中使用websocket进行通信功能,主要实现 WebSocket 的连接、断开、重连、发送消息等功能,并且通过 eventBus 实现了消息的跨组件通信。

  1. 需要先执行通信下载指令:npm install websocket。
  2. 组件通信需要安装eventbus进行。
EventBus安装使用步骤

1.在vue3+ts中,移除了内置的eventBus,当前展示安装和使用 mitt 的步骤。

下载指令:npm install mitt

2.创建 EventBus.ts文件,用于初始化 mitt 并导出事件总线实例。

import mitt, { Emitter } from 'mitt';

// 定义事件类型
type Events = {
  socketMsg: string; // 自定义事件名称和数据类型
  // 可以添加更多事件类型
};

// 创建事件总线实例
const eventBus: Emitter<Events> = mitt<Events>();

export default eventBus;

3.使用EventBus,页面使用包含发送,接收,移除。使用生命周期w为onMounted 和 onUnmounted

// ts文件引入
import eventBus from './eventBus';

// 发送事件
eventBus.emit('socketMsg', 'Hello from WebSocket');

// 监听事件
eventBus.on('socketMsg', (message) => {
  console.log('Received message:', message);
});

// 移除事件监听
eventBus.off('socketMsg', handler);

执行完eventBus和websocket安装指令后,就可以进行socket的全局工具函数封装。

封装全局工具函数
import { ref } from 'vue';
import eventBus from '../eventBus';

// 标志位区分是手动断开还是意外断开
let isManualDisconnect = false;

export const useWebSocket = {
  socket: null as WebSocket | null, // 声明
  isConnected: ref(false), // 判断当前连接状态
  reconnectAttempts: 0, // 默认重连数
  maxReconnectAttempts: 5, // 最大重连数
  reconnectInterval: 3000, // 重连间隔

  // 连接 WebSocket 服务器,监听相关事件
  connect(url: string) {
    if (this.socket) {
      return
    }
    this.socket = new WebSocket(url)

    this.socket.onopen = () => {
      this.isConnected.value = true;
      this.reconnectAttempts = 0;
      console.log('WebSocket连接已打开');
    };

    this.socket.onclose = () => {
      this.isConnected.value = false;
      console.log('WebSocket连接已关闭');
      if (!isManualDisconnect) {
        this.reconnect();
      }
    };

    this.socket.onerror = (error: Event) => {
      console.error('WebSocket error:', error);
    };

    this.socket.onmessage = (event: MessageEvent) => {
      console.log('收到消息:', event.data);
      eventBus.emit('socketMsg', event.data)
    };
  },
  // 关闭链接
  disconnect() {
    isManualDisconnect = true
    if (this.socket) {
      this.socket.close();
      this.socket = null;
      this.isConnected.value = false;
    }
  },
  // 尝试重连
  reconnect() {
    if (isManualDisconnect) {
      console.log('Manual disconnect, no reconnect needed');
      return;
    }
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      console.log(`Reconnecting attempt ${this.reconnectAttempts}`);
      setTimeout(() => {
        this.connect(this.socket?.url || '');
      }, this.reconnectInterval);
    } else {
      console.error('Max reconnect attempts reached');
    }
  },
  // 发送消息
  sendMessage(message: string) {
    if (this.isConnected.value && this.socket) {
      this.socket.send(message);
      console.log('WebSocket message sent:', message);
    } else {
      console.error('WebSocket is not connected');
    }
  },
}

上述步骤完成后即可再组件内进行组件实时通信。

// html引用监听
<script setup lang="ts">
import { useWebSocket } from "./utils/useWebsocket";

onMounted(() => {
  // 自定义连接事件、位置、url
  useWebSocket.connect(`ws://192.168.1.41:8080/manage/conn`);

  // 接收eventbus传参的信息,并可手动关闭连接或者发送信息文本。
  eventBus.on("socketMsg", async (item: any) => {
    // 手动关闭连接
    useWebSocket.disconnect();

    // 发送信息
    useWebSocket.sendMessage(`发送信息文本`);
  })
})

// 离开页面销毁eventbus事件
onUnmounted(() => {
  eventBus.off("socketMsg");
});
</script>
### Vue3封装 WebSocket 的方法指南 在 Vue3 项目中,为了使代码更具有模块化和可维护性,通常会将 WebSocket 功能进行单独封装。这不仅有助于简化组件内的逻辑处理,还能提高代码的重用性和测试便利性。 #### 创建 WebSocket 封装类 通过定义一个专门用于管理 WebSocket 连接和服务交互的 JavaScript 类来实现这一目标。此类负责初始化连接、监听消息事件以及发送数据给服务器等功能[^1]。 ```javascript // src/utils/websocketService.js import { ref, onMounted, onUnmounted } from &#39;vue&#39;; class WebSocketService { constructor(url) { this.url = url; this.socketRef = ref(null); this.connect(); } connect() { const socket = new WebSocket(this.url); socket.onopen = () => console.log(&#39;Connected to server&#39;); socket.onerror = (error) => console.error(`WebSocket error: ${error}`); socket.onmessage = (event) => this.handleMessage(event.data); socket.onclose = () => console.warn(&#39;Disconnected from server&#39;); this.socketRef.value = socket; } sendMessage(message) { if (this.isConnected()) { this.socketRef.value.send(JSON.stringify(message)); } } handleMessage(data) { try { const parsedData = JSON.parse(data); // 处理收到的消息... } catch (e) { console.error(&#39;Failed to parse message:&#39;, e); } } isConnected() { return this.socketRef.value && this.socketRef.value.readyState === WebSocket.OPEN; } closeConnection() { if (this.isConnected()) { this.socketRef.value.close(); } } } export default WebSocketService; ``` 此部分实现了 WebSocket 的基础功能,并利用 `ref` 来追踪当前实例的状态变化。当页面加载完成时自动建立连接;而在卸载前关闭它以防止资源泄漏[^2]。 #### 使用 Composition API 集成到组件内 为了让其他地方能够方便地调用上述服务,在实际应用过程中可以通过组合式API的方式引入并注册该服务: ```javascript // src/components/WebSocketComponent.vue <template> <div class="ws-component"> <!-- 组件模板 --> </div> </template> <script setup> import { watchEffect } from "vue"; import WebSocketService from "@/utils/websocketService"; const wsUrl = import.meta.env.VITE_WS_URL || &#39;wss://example.com/socket&#39;; const webSocketInstance = new WebSocketService(wsUrl); watchEffect(() => { // 可在此处添加对webSocketInstance的操作逻辑 }); </script> ``` 这里采用了 `<script setup>` 新特性使得语法更为简洁明了。同时借助于 `watchEffect` 实现响应式的操作模式,确保每当依赖项发生变化时都能及时更新视图状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值