uni webSocket 封装

524 阅读1分钟

一、在utils文件夹新建一个websocket.js

import { BASE_WS_URL } from "@/api/request"; //这边是在requset.js做配置项把请求地址前缀做统一配置
class webSocketClass {
   // parmas链接需要携带的参数对象
   // interval心跳执行间隔
  constructor(params, interval) { 
    this.url = BASE_WS_URL + this.objectToQuery(params);//把参数转为字符串链接
    this.data = null;
    this.isCreate = false; // WebSocket 是否创建成功
    this.isConnect = false; // 是否已经连接
    this.isInitiative = false; // 是否主动断开
    this.heartbeatInterval = interval; // 心跳检测间隔
    this.heartbeatTimer = null; // 心跳检测定时器
    this.reconnectTimer = null; // 断线重连定时器
    this.socketExamples = null; // websocket实例
    this.againTime = 3; // 重连等待时间(单位秒)
  }

  // 初始化websocket连接
  initSocket() {
    const _this = this;
    this.socketExamples = uni.connectSocket({
      url: _this.url,
      method: "GET",
      success: (res) => {
        _this.isCreate = true;
      },
      fail: (rej) => {
        console.error(rej);
        _this.isCreate = false;
      },
    });
    this.createSocket();
  }

  // 创建websocket连接
  createSocket() {
    console.log("WebSocket 开始初始化");
    if (this.isCreate) {
      // 监听 WebSocket 连接打开事件
      try {
        this.socketExamples.onOpen(() => {
          console.log("WebSocket 连接成功");
          this.isConnect = true;
          clearInterval(this.heartbeatTimer);
          clearTimeout(this.reconnectTimer);
          // 打开心跳检测
          this.heartbeatCheck()
        });
        // 监听 WebSocket 接受到服务器的消息事件
        this.socketExamples.onMessage((res) => {
          // console.log("收到消息",res);
          uni.$emit("message", res);
        });
        // 监听 WebSocket 连接关闭事件
        this.socketExamples.onClose(() => {
          console.log("WebSocket 关闭了");
          this.isConnect = false;
          this.reconnect();
        });
        // 监听 WebSocket 错误事件
        this.socketExamples.onError((res) => {
          console.log("WebSocket 出错了");
          this.reconnect();
        });
      } catch (error) {
        console.warn(error);
      }
    } else {
      console.warn("WebSocket 初始化失败!");
    }
  }

  // 发送消息
  sendMsg(value) {
    const param = JSON.stringify(value);
    return new Promise((resolve, reject) => {
      this.socketExamples.send({
        data: param,
        success() {
          console.log("消息发送成功");
          resolve(true);
        },
        fail(error) {
          console.log("消息发送失败");
          reject(error);
        },
      });
    });
  }

    // 接受数据
    onSocketMsg(value) {
      return new Promise((resolve, reject) => {
        this.socketExamples.send({
          data: param,
          success() {
            console.log("消息发送成功");
            resolve(true);
          },
          fail(error) {
            console.log("消息发送失败");
            reject(error);
          },
        });
      });
    }

  // 开启心跳检测
  heartbeatCheck() {
    console.log("开启心跳");
    this.data = { state: 1, method: "heartbeat" };
    this.heartbeatTimer = setInterval(() => {
      this.sendMsg(this.data);
    }, this.heartbeatInterval * 1000);
  }

  // 重新连接
  reconnect() {
    // 停止发送心跳
    clearInterval(this.heartbeatTimer);
    clearTimeout(this.reconnectTimer);
    // 如果不是人为关闭的话,进行重连
    if (!this.isInitiative) {
      this.reconnectTimer = setTimeout(() => {
        this.initSocket();
      }, this.againTime * 1000);
    }
  }

  // 关闭 WebSocket 连接
  closeSocket(reason = "关闭") {
    const _this = this;
    this.socketExamples.close({
      reason,
      success() {
        _this.data = null;
        _this.isCreate = false;
        _this.isConnect = false;
        _this.isInitiative = true;
        _this.socketExamples = null;
        clearInterval(_this.heartbeatTimer);
        clearTimeout(_this.reconnectTimer);
        console.log("关闭 WebSocket 成功");
      },
      fail() {
        console.log("关闭 WebSocket 失败");
      },
    });
  }
  // 把对象为链接
  objectToQuery() {
    let obj = arguments[0];
    let prefix = arguments[1];
    if (typeof obj !== "object") return "";
    const attrs = Object.keys(obj);
    return attrs.reduce((query, attr, index) => {
      if (index === 0 && !prefix) query += "?";
      if (typeof obj[attr] === "object") {
        const subPrefix = prefix ? `${prefix}[${attr}]` : attr;
        query += this.objectToQuery(obj[attr], subPrefix);
      } else {
        if (prefix) {
          query += `${prefix}[${attr}]=${obj[attr]}`;
        } else {
          query += `${attr}=${obj[attr]}`;
        }
      }
      if (index !== attrs.length - 1) query += "&";
      return query;
    }, "");
  }
}


export default webSocketClass;

二、在需要使用的页面上引入webSocketClass并初始化

import webSocketClass from "@/utils/webSocket";
export default{
 data(){
   return{
     socketObj:null, // 初始化
     params:null // 长链接参数
   }
 }
 onLoad(){
     // 初始化长链接
     this.socketObj = new webSocketClass(params,300);
     this.socketObj.initSocket();
     uni.$on("message", (data) => {
       console.log('data',data) // 监听取值
     });
 },
 // 页面关闭,销毁长链接
 deactivated() {
    this.socketObj.closeSocket();
  },
}