WebSocketComponent.vue

<template>
  <div>
    <p v-if="message">Received Message: {{ message }}</p>
  </div>
</template>

<script>
export default {
  name: 'WebSocketComponent',
  props: {
    url: {
      type: String,
      required: true // URL 是一个必需的字符串参数
    },
    mechanismId: {
      type: String,
      required: true // mechanismId 是一个必需的字符串参数
    }
  },
  data() {
    return {
      ws: null, // WebSocket 对象
      warning: false, // 用于跟踪心跳是否中断
      message: null, // 接收到的消息
      lockReconnect: false, // 防止多次重连的锁
      timeout: 15000, // 心跳间隔时间,15 秒
      timeoutObj: null, // 心跳计时器
      serverTimeoutObj: null, // 服务器响应计时器
      timeoutnum: null, // 重连计时器
    };
  },
  methods: {
    // 初始化 WebSocket 连接
    initWebSocket() {
      const finalUrl = `${this.url}/report${this.mechanismId}_${this.randomString(32)}`;
      this.ws = new WebSocket(finalUrl);

      // 设置 WebSocket 事件回调
      this.ws.onopen = this.onOpen;
      this.ws.onerror = this.onError;
      this.ws.onmessage = this.onMessage;
      this.ws.onclose = this.onClose;
    },
    // WebSocket 连接成功时调用
    onOpen() {
      console.log("WebSocket connected successfully");
      this.startHeartbeat();
    },
    // WebSocket 连接错误时调用
    onError() {
      console.log("WebSocket connection error");
      this.reconnect();
    },
    // 接收到服务器消息时调用
    onMessage(event) {
      if (event.data === "ping") {
        // 如果收到服务器心跳包,重置心跳计时器
        this.warning = false;
        this.resetHeartbeat();
      } else {
        // 处理其他消息
        this.warning = true;
        this.message = event.data;
      }
    },
    // WebSocket 连接关闭时调用
    onClose() {
      console.log("WebSocket connection closed");
      this.reconnect();
    },
    // 启动心跳
    startHeartbeat() {
      clearTimeout(this.timeoutObj); // 清除之前的心跳计时器
      clearTimeout(this.serverTimeoutObj); // 清除之前的服务器响应计时器
      this.timeoutObj = setTimeout(() => {
        this.ws.send("ping"); // 发送心跳包
        this.serverTimeoutObj = setTimeout(() => {
          this.ws.close(); // 如果服务器没有响应,关闭连接
        }, this.timeout);
      }, this.timeout);
    },
    // 重置心跳
    resetHeartbeat() {
      clearTimeout(this.timeoutObj); // 清除心跳计时器
      clearTimeout(this.serverTimeoutObj); // 清除服务器响应计时器
      this.startHeartbeat(); // 重新启动心跳
    },
    // 重连逻辑
    reconnect() {
      if (this.lockReconnect) return; // 如果已经在重连中,直接返回
      this.lockReconnect = true; // 设置重连锁
      clearTimeout(this.timeoutnum); // 清除重连计时器
      this.timeoutnum = setTimeout(() => {
        this.initWebSocket(); // 重新初始化 WebSocket
        this.lockReconnect = false; // 释放重连锁
      }, 5000); // 5 秒后重连
    },
    // 生成随机字符串
    randomString(length) {
      let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      let result = '';
      for (let i = 0; i < length; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
      }
      return result;
    },
    // 关闭 WebSocket 连接
    closeWebSocket() {
      this.ws.close();
    }
  },
  // 在组件挂载时初始化 WebSocket 连接
  mounted() {
    this.initWebSocket();
  },
  // 在组件销毁前关闭 WebSocket 连接
  beforeDestroy() {
    this.closeWebSocket();
  }
};
</script>

<style scoped>
/* 添加你的样式 */
</style>

使用 WebSocket 组件

在你的主组件或者需要使用 WebSocket 的地方引入并使用这个 WebSocket 组件。

<template>
  <div>
    <WebSocketComponent 
      :url="webSocketUrl" 
      :mechanismId="userMechanismId" 
    />
  </div>
</template>

<script>
import WebSocketComponent from '@/components/WebSocketComponent.vue';
import user from './user';

export default {
  name: 'MainComponent',
  components: {
    WebSocketComponent
  },
  data() {
    return {
      webSocketUrl: process.env.VUE_APP_SOCKET_API, // 动态配置 WebSocket URL
      userMechanismId: user.state.mechanismId // 从你的用户模块中获取
    };
  }
};
</script>

<style scoped>
/* 添加你的样式 */
</style>

配置环境变量

确保你的 .env 文件中包含 WebSocket URL。

VUE_APP_SOCKET_API=https://example.com

用户模块(user.js)

确保用户模块正确导出 mechanismId

const state = {
  mechanismId: 'your_mechanism_id'
};

export default {
  state,
  // 其他 user 模块的内容
};

测试和调试

  1. 控制台日志:检查浏览器控制台,确保看到 "WebSocket connected successfully"、"WebSocket connection error" 和 "WebSocket connection closed" 的日志。
  2. 消息接收:在服务器端发送消息,确保客户端能够正确接收并显示消息。
  3. 心跳和重连:在网络断开和恢复的情况下,检查组件是否能够正确进行心跳检测和重连。
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐