vue中webSocket的封装及使用

一  websocket的简介

Websocket 是一种在单个 TCP 连接上进行全双工通信的协议。它使得服务器和客户端之间可以实现实时的、双向的数据传输,与传统的 HTTP 请求 - 响应模式不同。传统的 HTTP 通信是单向的,客户端发起请求,服务器响应,然后连接关闭。而 Websocket 允许服务器主动向客户端推送数据,并且在建立连接后可以持续通信。

二  websocket的封装及使用

1、新建websoket.js
import Vue from 'vue';
class websocketObj {
  constructor(url) {
    // WebSocket连接地址
    this.url = url;
    // WebSocket实例对象
    this.socket = null;
    // 心跳定时器
    this.heartInterval = null;
    // 重连定时器
    this.reconnectTimer = null;
    // 心跳消息(可根据服务端要求自定义)
    this.pingMessage = {
      type: 'heartInterval',
      content: '心跳检测正常'
    };
    // 重连次数
    this.reconnectCount = 0;
    // 最大重连次数
    this.maxReconnectCount = 10;
    // 重连时间间隔
    this.reconnectInterval = 3000;
    // 存储消息
    this.receiveMessage = {};
  }

  // 连接WebSocket方法
  connect () {
    this.socket = new WebSocket(this.url);
    this.socket.onopen = this.onOpen.bind(this);
    this.socket.onmessage = this.onMessage.bind(this);
    this.socket.onclose = this.onClose.bind(this);
    this.socket.onerror = this.onError.bind(this);
  }

  // 连接打开时的回调
  onOpen () {
    console.log('盼盼测试链接socket,链接正常');
    // 开启心跳检测
    this.startPing();
  }

  // 接收到消息时的回调
  onMessage (event) {
    const message = event.data;
    let messageData = null;
    try {
      messageData = JSON.parse(message);
    } catch (error) {
      messageData = message;
    }
    // 判断是否有消息
    if (messageData) {
      const messageType = messageData.type;
      if (this.receiveMessage[messageType]) {
        this.receiveMessage[messageType].forEach(callback => {
          callback(messageData);
        });
      }
    }
    // 收到消息后重置心跳检测
    this.resetPing();
  }

  // 连接关闭时
  onClose (event) {
    console.log('WebSocket连接已关闭', event);
    // 清除心跳定时器
    this.clearPing();
    // 判断是否需要重连
    if (this.reconnectCount < this.maxReconnectCount) {
      this.reconnect();
    } else {
      console.log('已达到最大重连次数,不再尝试重连');
    }
  }

  // 出现错误时的回调
  onError (error) {
    console.log('WebSocket出现错误:', error);
    // 关闭连接,触发onClose方法来进行后续处理(如重连判断等)
    this.socket.close();
  }

  // 发送消息方法
  send (message) {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(message);
    } else {
      console.log('WebSocket未连接或连接不可用,无法发送消息');
    }
  }

  // 开启心跳检测
  startPing () {
    this.heartInterval = setInterval(() => {
      this.send(JSON.stringify(this.pingMessage));
    }, 5000); // 心跳间隔时间,这里设置为5秒,可按需调整
  }

  // 重置心跳检测(重新计时)
  resetPing () {
    clearInterval(this.heartInterval);
    this.startPing();
  }

  // 清除心跳定时器
  clearPing () {
    clearInterval(this.heartInterval);
  }

  // 重连方法
  reconnect () {
    this.reconnectCount++;
    console.log(`第${this.reconnectCount}次尝试重连...`);
    this.reconnectTimer = setTimeout(() => {
      this.connect();
    }, this.reconnectInterval);
  }

  // 接收消息回调
  subscribe (messageType, callback) {
    console.log(messageType, callback)
    if (!this.receiveMessage[messageType]) {
      this.receiveMessage[messageType] = [];
    }
    this.receiveMessage[messageType].push(callback);
  }
  // 删除消息回调
  unsubscribe (messageType, callback) {
    if (this.receiveMessage[messageType]) {
      const index = this.receiveMessage[messageType].indexOf(callback);
      if (index > -1) {
        this.receiveMessage[messageType].splice(index, 1);
      }
    }
  }
}

// 创建单例模式的WebSocketManager实例
const webSocketManager = new websocketObj('ws://localhost:8888/websocket/123');

// 导出实例以及Vue的混入方法(用于方便组件使用)
export default {
  install (Vue) {
    Vue.prototype.$socketApi = webSocketManager;
  },
  webSocketManager
};
2、main.js 挂载
import WebSocketManager from '@/common/js/websoket.js';
Vue.use(WebSocketManager)
3、vue页面使用
  mounted () {
    this.$socketApi.connect();// 启动websocket
  
  },
4、vue页面发送消息
 methods: {
    sendMessage () {  //发送消息方法
      let a = {
        type: '1',
        common: '卫盼1'
      }
      let b = {
        type: '2',
        common: '卫盼2'
      }
      let c = {
        type: '3',
        common: '卫盼3'
      }
      let d = {
        type: '4',
        common: '卫盼4'
      }
      this.$socketApi.send(JSON.stringify(a));
      this.$socketApi.send(JSON.stringify(b));
      this.$socketApi.send(JSON.stringify(c));
      this.$socketApi.send(JSON.stringify(d));
    }
  },
5、页面消息接收
mounted () {
    this.$socketApi.connect();// 启动websocket
    this.$socketApi.subscribe('1', (message) => {
      this.data.push(message)
    });
    this.$socketApi.subscribe('2', (message) => {
      this.data.push(message)
    });
    this.$socketApi.subscribe('3', (message) => {
      this.data.push(message)
    });
    this.$socketApi.subscribe('4', (message) => {
      this.data.push(message)
    });
  },
6、当组件销毁时,关闭 WebSocket 连接以及清除重连定时器,避免出现内存泄漏等问题。
  beforeDestroy () {
    // 组件销毁时,关闭WebSocket连接并清除定时器
    if (this.$socketApi.socket) {
      this.$socketApi.socket.close();
    }
    if (this.$socketApi.reconnectTimer) {
      clearTimeout(this.$socketApi.reconnectTimer);
    }
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值