|  | @@ -0,0 +1,112 @@
 | 
	
		
			
				|  |  | +import CryptoJS from 'crypto-js'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export class LiveWS {
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * @param {string} url - WebSocket 服务器地址
 | 
	
		
			
				|  |  | +   * @param {number} liveId - 直播间ID
 | 
	
		
			
				|  |  | +   * @param {number} userId - 用户ID
 | 
	
		
			
				|  |  | +   * @param {number} checkInterval - 检查连接状态的时间间隔,单位毫秒
 | 
	
		
			
				|  |  | +   * @param {number} reconnectDelay - 连接断开后重连的延迟,单位毫秒
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  constructor(url, liveId, userId, checkInterval = 5000, reconnectDelay = 3000) {
 | 
	
		
			
				|  |  | +    let timestamp = new Date().getTime()
 | 
	
		
			
				|  |  | +    let userType = 1
 | 
	
		
			
				|  |  | +    let signature = CryptoJS.HmacSHA256(
 | 
	
		
			
				|  |  | +      CryptoJS.enc.Utf8.parse('' + liveId + userId + userType + timestamp),
 | 
	
		
			
				|  |  | +      CryptoJS.enc.Utf8.parse(timestamp)).toString(CryptoJS.enc.Hex)
 | 
	
		
			
				|  |  | +    this.url = url + `?liveId=${liveId}&userId=${userId}&userType=${userType}×tamp=${timestamp}&signature=${signature}`;
 | 
	
		
			
				|  |  | +    console.log(this.url)
 | 
	
		
			
				|  |  | +    this.liveId = liveId;
 | 
	
		
			
				|  |  | +    this.userId = userId;
 | 
	
		
			
				|  |  | +    this.checkInterval = checkInterval;
 | 
	
		
			
				|  |  | +    this.reconnectDelay = reconnectDelay;
 | 
	
		
			
				|  |  | +    this.ws = null;
 | 
	
		
			
				|  |  | +    this.reconnectTimer = null;
 | 
	
		
			
				|  |  | +    this.heartbeatTimer = null;
 | 
	
		
			
				|  |  | +    this.isManualClose = false;
 | 
	
		
			
				|  |  | +    this.connect();
 | 
	
		
			
				|  |  | +    this.startHeartbeat();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  connect() {
 | 
	
		
			
				|  |  | +    // 如果已经有一个连接处于 OPEN 或 CONNECTING 状态,则不再创建新连接
 | 
	
		
			
				|  |  | +    if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.ws = new WebSocket(this.url);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 绑定事件
 | 
	
		
			
				|  |  | +    this.ws.onopen = (event) => {
 | 
	
		
			
				|  |  | +      // 连接成功后,清除重连计时器
 | 
	
		
			
				|  |  | +      if (this.reconnectTimer) {
 | 
	
		
			
				|  |  | +        clearTimeout(this.reconnectTimer);
 | 
	
		
			
				|  |  | +        this.reconnectTimer = null;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.ws.onmessage = (event) => {
 | 
	
		
			
				|  |  | +      this.onmessage(event);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.ws.onerror = (error) => {
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.ws.onclose = (event) => {
 | 
	
		
			
				|  |  | +      // 如果不是主动关闭,则重连
 | 
	
		
			
				|  |  | +      if (!this.isManualClose) {
 | 
	
		
			
				|  |  | +        setTimeout(() => this.reconnect(), this.reconnectDelay);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  onmessage(event) {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  reconnect() {
 | 
	
		
			
				|  |  | +    this.connect();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 调度重连
 | 
	
		
			
				|  |  | +  scheduleReconnect() {
 | 
	
		
			
				|  |  | +    // 避免多次重连定时器同时存在
 | 
	
		
			
				|  |  | +    if (this.reconnectTimer) return;
 | 
	
		
			
				|  |  | +    this.reconnectTimer = setTimeout(() => {
 | 
	
		
			
				|  |  | +      this.connect();
 | 
	
		
			
				|  |  | +    }, this.reconnectDelay);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 定时检查连接状态
 | 
	
		
			
				|  |  | +  startHeartbeat() {
 | 
	
		
			
				|  |  | +    this.heartbeatTimer = setInterval(() => {
 | 
	
		
			
				|  |  | +      if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
 | 
	
		
			
				|  |  | +        this.scheduleReconnect();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 发送信息
 | 
	
		
			
				|  |  | +        this.ws.send(JSON.stringify({'cmd':'heartbeat','msg':'ping', 'liveId': this.liveId, 'userId': this.userId}));
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, this.checkInterval);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 主动关闭 WebSocket 连接,并清除定时任务
 | 
	
		
			
				|  |  | +  close() {
 | 
	
		
			
				|  |  | +    this.isManualClose = true;
 | 
	
		
			
				|  |  | +    if (this.heartbeatTimer) {
 | 
	
		
			
				|  |  | +      clearInterval(this.heartbeatTimer);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (this.reconnectTimer) {
 | 
	
		
			
				|  |  | +      clearTimeout(this.reconnectTimer);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (this.ws) {
 | 
	
		
			
				|  |  | +      this.ws.close();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 发送消息方法
 | 
	
		
			
				|  |  | +  send(message) {
 | 
	
		
			
				|  |  | +    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
 | 
	
		
			
				|  |  | +      this.ws.send(message);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      console.error("WebSocket is not open. Message not sent.");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 |