vue3中的websocket应用

3,767 阅读4分钟

在 Vue 3 中使用 WebSocket 进行数据传输时,确保 WebSocket 连接的稳定性和实现重连机制是非常重要的,尤其是在网络不稳定或 WebSocket 连接中断的情况下。以下是实现 WebSocket 连接保持和重连机制的详细步骤和代码示例。

一、WebSocket 基本概念

WebSocket 是一种在客户端和服务器之间建立持久性连接的协议。相比于传统的 HTTP 请求,WebSocket 允许双向通信,使得服务器能够主动向客户端推送消息。

二、基本的 WebSocket 客户端

首先,我们需要在 Vue 3 中使用 WebSocket。可以在 Vue 组件中创建 WebSocket 客户端,并监听不同的事件。

<template>
  <div>
    <h1>WebSocket Example</h1>
    <p>Current Message: {{ message }}</p>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount } from "vue";

export default {
  setup() {
    const message = ref(""); // 用于展示从 WebSocket 获取的消息
    let ws = null; // WebSocket 实例
    let reconnectTimeout = null; // 重连超时控制

    // 建立 WebSocket 连接
    const connectWebSocket = () => {
      ws = new WebSocket("wss://example.com/socket"); // 替换为实际的 WebSocket 服务 URL

      ws.onopen = () => {
        console.log("WebSocket 连接已建立");
      };

      ws.onmessage = (event) => {
        message.value = event.data; // 接收到服务器推送的消息
      };

      ws.onerror = (error) => {
        console.error("WebSocket 发生错误", error);
      };

      ws.onclose = (event) => {
        console.log("WebSocket 连接已关闭", event.code);
        handleReconnect(); // WebSocket 连接关闭时尝试重连
      };
    };

    // 处理 WebSocket 连接断开后的重连
    const handleReconnect = () => {
      // 如果已经在重连,避免重复重连
      if (reconnectTimeout) {
        return;
      }

      reconnectTimeout = setTimeout(() => {
        console.log("正在尝试重新连接 WebSocket...");
        connectWebSocket();
        reconnectTimeout = null; // 重连后清除重连超时
      }, 5000); // 5 秒后重连
    };

    onMounted(() => {
      connectWebSocket(); // 组件加载时连接 WebSocket
    });

    onBeforeUnmount(() => {
      if (ws) {
        ws.close(); // 组件销毁时关闭 WebSocket 连接
      }
    });

    return {
      message,
    };
  },
};
</script>

三、保证 WebSocket 不会断开连接且有重连机制

为了保证 WebSocket 不会断开且具有重连机制,我们可以通过以下几种策略来管理连接的生命周期:

  1. 连接管理: 在 WebSocket 连接关闭时,尝试重新连接。
  2. 自动重连: 如果连接丢失或断开,设置一个重连机制,定时重新连接。
  3. 心跳机制: 通过定时发送心跳包,确保连接保持活跃,避免由于长时间没有数据传输而被服务器断开。

3.1 连接管理与重连机制

在前面的代码示例中,我们已经实现了 ws.onclose 事件来监听 WebSocket 连接的关闭,并在连接关闭时尝试重连。通过设置一个 setTimeout,我们实现了简单的重连机制。

3.2 心跳机制

为了保持 WebSocket 连接的稳定性,我们可以定期发送心跳包(一个简单的消息)来避免服务器由于长时间没有数据传输而主动断开连接。

const sendHeartbeat = () => {
  if (ws && ws.readyState === WebSocket.OPEN) {
    console.log("发送心跳包");
    ws.send(JSON.stringify({ type: "heartbeat" })); // 自定义心跳包的格式
  }
};

// 每隔 30 秒发送一次心跳包
const heartbeatInterval = setInterval(sendHeartbeat, 30000);

// 在 WebSocket 关闭时清除心跳
onBeforeUnmount(() => {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval);
  }
});

3.3 处理 WebSocket 状态变化

WebSocket 有不同的状态,如 CONNECTINGOPENCLOSINGCLOSED,可以根据状态来判断当前的连接是否可用。

const checkConnectionStatus = () => {
  if (ws.readyState === WebSocket.OPEN) {
    console.log("WebSocket 连接正常");
  } else if (ws.readyState === WebSocket.CONNECTING) {
    console.log("WebSocket 正在连接...");
  } else if (ws.readyState === WebSocket.CLOSING) {
    console.log("WebSocket 连接正在关闭...");
  } else if (ws.readyState === WebSocket.CLOSED) {
    console.log("WebSocket 连接已关闭,准备重连");
    handleReconnect();
  }
};

// 每隔 5 秒检查一次连接状态
setInterval(checkConnectionStatus, 5000);

四、完整示例代码

<template>
  <div>
    <h1>WebSocket Example</h1>
    <p>Current Message: {{ message }}</p>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount } from "vue";

export default {
  setup() {
    const message = ref(""); // 用于展示从 WebSocket 获取的消息
    let ws = null; // WebSocket 实例
    let reconnectTimeout = null; // 重连超时控制
    const heartbeatInterval = 30000; // 设置心跳包发送时间间隔(30秒)

    // 建立 WebSocket 连接
    const connectWebSocket = () => {
      ws = new WebSocket("wss://example.com/socket"); // 替换为实际的 WebSocket 服务 URL

      ws.onopen = () => {
        console.log("WebSocket 连接已建立");
      };

      ws.onmessage = (event) => {
        message.value = event.data; // 接收到服务器推送的消息
      };

      ws.onerror = (error) => {
        console.error("WebSocket 发生错误", error);
      };

      ws.onclose = (event) => {
        console.log("WebSocket 连接已关闭", event.code);
        handleReconnect(); // WebSocket 连接关闭时尝试重连
      };
    };

    // 处理 WebSocket 连接断开后的重连
    const handleReconnect = () => {
      // 如果已经在重连,避免重复重连
      if (reconnectTimeout) {
        return;
      }

      reconnectTimeout = setTimeout(() => {
        console.log("正在尝试重新连接 WebSocket...");
        connectWebSocket();
        reconnectTimeout = null; // 重连后清除重连超时
      }, 5000); // 5 秒后重连
    };

    // 发送心跳包
    const sendHeartbeat = () => {
      if (ws && ws.readyState === WebSocket.OPEN) {
        console.log("发送心跳包");
        ws.send(JSON.stringify({ type: "heartbeat" })); // 自定义心跳包的格式
      }
    };

    // 检查 WebSocket 连接状态
    const checkConnectionStatus = () => {
      if (ws.readyState === WebSocket.OPEN) {
        console.log("WebSocket 连接正常");
      } else if (ws.readyState === WebSocket.CONNECTING) {
        console.log("WebSocket 正在连接...");
      } else if (ws.readyState === WebSocket.CLOSING) {
        console.log("WebSocket 连接正在关闭...");
      } else if (ws.readyState === WebSocket.CLOSED) {
        console.log("WebSocket 连接已关闭,准备重连");
        handleReconnect();
      }
    };

    onMounted(() => {
      connectWebSocket(); // 组件加载时连接 WebSocket

      // 每隔 30 秒发送一次心跳包
      setInterval(sendHeartbeat, heartbeatInterval);

      // 每隔 5 秒检查一次 WebSocket 状态
      setInterval(checkConnectionStatus, 5000);
    });

    onBeforeUnmount(() => {
      if (ws) {
        ws.close(); // 组件销毁时关闭 WebSocket 连接
      }
    });

    return {
      message,
    };
  },
};
</script>

五、总结

在 Vue 3 中使用 WebSocket 进行数据传输时,确保连接的稳定性和实现重连机制非常重要。我们可以通过以下方式保障 WebSocket 的可靠性:

  1. 重连机制:当 WebSocket 连接断开时,尝试重新连接。
  2. 心跳机制:定期发送心跳包,保持连接活跃,避免因长时间未通信而被服务器断开连接。
  3. WebSocket 状态管理:根据 WebSocket 的不同状态进行相应的处理,如重连、检查连接等。