import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
class WebSocket {
  // 构造函数
  constructor() {
    this.host = sessionStorage.getItem('wshost') || '';
    this.tryTimes = 1; // 重连次数
    this.callback = null; // 回调函数
    this.client = null; // stomp对象
    this.reconTimeout = null; // 重连延时器
    this.debug = true; // 调试
    this.interval = 20; // 重连间隔时间
    this.vm = null;
    this.nextDate = 0;
    this.connects = 1;
    this.recon = false;
    this.sendTimeout = null;
    this.socket = null;
    this.subscription = null;
  }

  /** socket连接 */
  connect() {
    if (!this.client) {
    // 连接SockJS
      this.socket = new SockJS(this.host + this.url, {timeout: 60000});
      this.client = Stomp.over(this.socket);
    }

    // 日志不打印
    if (!this.debug) {
      this.client.debug = () => {};
    }

    // 向服务器发起websocket连接
    this.client.connect({}, () => {
      this.recon = true;
      // tryTimes定义重置
      this.connects = 1;
      // 订阅消息
      this.subscribe();
    }, (error) => {
      this.unsubscribe();
      this.client = null;
      let diffSecond = parseInt((new Date() - this.nextDate) / 1000, 10);
      if (this.connects > 5 && diffSecond < this.interval) {
        this.error && this.error(error);
      } else {
        this.reconTimeout = setTimeout(() => {
          this.connect();
          this.connects++;
        }, 5000);
      }
    });
  }// 清除订阅
  unsubscribe() {
    if (this.subscription) {
      this.subscription.unsubscribe();
      this.subscription = null;
    }
  }
  /** 订阅服务端 */
  subscribe() {
    // 订阅服务端提供的某个topic
    this.subscription = this.client.subscribe(this.take, (response) => {
      if (response && (this.callback || this.success)) {
        let callback = this.callback || this.success;
        callback(JSON.parse(response.body));
      }
    });
  }

  /** 赋值、初始化socket */
  init(option, vm) {
    for (let i in option) {
      this[i] = option[i];
    }
    this.vm = vm;
    // 初始化连接
    this.connect();
  }

  /** 发送消息 */
  send(data) {
    if (this.recon) {
      clearTimeout(this.sendTimeout);
      this.client.send(this.take, {}, typeof data === 'string' ? data : JSON.stringify(data));
    } else {
      this.sendTimeout = setTimeout(() => {
        this.send(data);
      }, 1000);
    }
  }

  /** 销毁 */
  destroy() {
    // 断开连接,清除定时器
    this.unsubscribe();
    if (this.client) {
      this.client.disconnect();
    };
    this.reconTimeout && clearTimeout(this.reconTimeout);
    this.sendTimeout && clearTimeout(this.sendTimeout);
  }
}

export default WebSocket;
