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}`; 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."); } } }