websocket封装

websocket+ts通用组件

/* eslint-disable no-console */
// socket主要对象
// eslint-disable-next-line camelcase
export default function socket(ws_url: string) {
  const socket = {
    websock: null as any,
    ws_url,
    // 开启标识
    socket_open: false,
    // 心跳timer
    hearbeat_timer: null as any,
    // 心跳发送频率
    hearbeat_interval: 5000,

    // 是否自动重连
    is_reonnect: true,
    // 重连次数
    reconnect_count: 3,
    // 已发起重连次数
    reconnect_current: 1,
    // 重连timer
    reconnect_timer: null as any,
    // 重连频率
    reconnect_interval: 3000,

    /**
     * 初始化连接
     */
    init: (cb?: any) => {
      if (!("WebSocket" in window)) {
        console.log("浏览器不支持WebSocket");
        return null;
      }

      // 已经创建过连接不再重复创建
      if (socket.websock) {
        return socket.websock;
      }

      socket.websock = new WebSocket(socket.ws_url);
      socket.websock.onmessage = (e: any) => {
        socket.receive(e, cb);
      };

      // 关闭连接
      socket.websock.onclose = (e: { code: any }) => {
        console.log("连接已断开");
        console.log(`connection closed (${e.code})`);
        clearInterval(socket.hearbeat_interval);
        socket.socket_open = false;

        // 需要重新连接
        if (socket.is_reonnect) {
          socket.reconnect_timer = setTimeout(() => {
            // 超过重连次数
            if (socket.reconnect_current > socket.reconnect_count) {
              clearTimeout(socket.reconnect_timer);
              return;
            }

            // 记录重连次数
            socket.reconnect_current += 1;
            socket.reconnect();
          }, socket.reconnect_interval);
        }
      };

      // 连接成功
      socket.websock.onopen = () => {
        console.log("连接成功");
        socket.socket_open = true;
        socket.is_reonnect = true;
        // 开启心跳
        socket.heartbeat();
      };

      // 连接发生错误
      socket.websock.onerror = () => {
        console.log("WebSocket连接发生错误");
      };
    },

    /**
     * 发送消息
     * @param {*} data 发送数据
     * @param {*} callback 发送后的自定义回调函数
     */
    send: (data: any, callback: any = null) => {
      // 开启状态直接发送
      if (socket.websock.readyState === socket.websock.OPEN) {
        socket.websock.send(JSON.stringify(data));

        if (callback) {
          callback();
        }

        // 正在开启状态,则等待1s后重新调用
      } else if (socket.websock.readyState === socket.websock.CONNECTING) {
        setTimeout(() => {
          socket.send(data, callback);
        }, 1000);

        // 未开启,则等待1s后重新调用
      } else {
        socket.init();
        setTimeout(() => {
          socket.send(data, callback);
        }, 1000);
      }
    },

    /**
     * 接收消息
     * @param {*} message 接收到的消息
     */
    receive: (message: any, cb: any) => {
      try {
        const params = JSON.parse(message.data);
        if (params !== null) {
          cb && cb(params);
        }
      } catch (error) {
        console.log(error);
      }
    },

    /**
     * 心跳
     */
    heartbeat: () => {
      console.log("socket", "ping");
      if (socket.hearbeat_timer) {
        clearInterval(socket.hearbeat_timer);
      }
      socket.hearbeat_timer = setInterval(() => {
        const data = null;
        socket.send(data);
      }, socket.hearbeat_interval);
    },

    /**
     * 主动关闭连接
     */
    close: () => {
      console.log("主动断开连接");
      clearInterval(socket.hearbeat_interval);
      socket.is_reonnect = false;
      socket.websock.close();
    },

    /**
     * 重新连接
     */
    reconnect: () => {
      console.log("发起重新连接", socket.reconnect_current);
      if (socket.websock && socket.socket_open) {
        socket.websock.close();
      }
      socket.websock = null;
      socket.init();
    },
  };
  return socket;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值