UNPKG

im-ui-mobile

Version:

A Vue3.0 + Typescript instant messaging component library for Uniapp

225 lines (188 loc) 6.02 kB
class WebSocket { constructor() { // 私有属性 this.messageCallBack = null; this.closeCallBack = null; this.connectCallBack = null; this.isConnect = false; this.reconnectTimer = null; this.lastConnectTime = new Date(); this.socketTask = null; // 心跳配置 this.heartCheckTimeout = 20000; this.heartCheckTimer = null; } // 私有方法 - 心跳相关 startHeartCheck() { if (!this.isConnect || !this.socketTask) return; // console.log('发送WebSocket心跳'); const heartBeat = { cmd: 1, data: {} }; this.sendMessage(JSON.stringify(heartBeat)); } resetHeartCheck() { this.clearHeartCheck(); this.heartCheckTimer = setTimeout(() => { this.startHeartCheck(); }, this.heartCheckTimeout); } clearHeartCheck() { if (this.heartCheckTimer) { clearTimeout(this.heartCheckTimer); this.heartCheckTimer = null; } } // 连接 WebSocket connect(wsurl, token) { if (this.isConnect) return; this.lastConnectTime = new Date(); this.socketTask = uni.connectSocket({ url: wsurl, fail: (e) => { console.error("WebSocket连接失败:", e); console.log("10秒后重连..."); this.scheduleReconnect(wsurl, token); } }); this.setupSocketEvents(token); } // 设置 WebSocket 事件监听 setupSocketEvents(token) { if (!this.socketTask) return; this.socketTask.onOpen(() => { // console.log("WebSocket连接成功"); this.isConnect = true; // 发送登录命令 const loginInfo = { cmd: 0, data: { accessToken: token } }; this.sendMessage(JSON.stringify(loginInfo)); }); this.socketTask.onMessage((res) => { try { const message = JSON.parse(res.data); this.handleMessage(message); } catch (error) { console.error("消息解析失败:", error); } }); this.socketTask.onClose((res) => { // console.log('WebSocket连接关闭', res); this.handleClose(res); }); this.socketTask.onError((e) => { console.error("WebSocket错误:", e); this.handleClose(e); }); } // 处理接收到的消息 handleMessage(message) { switch (message.cmd) { case 0: // 登录成功 this.resetHeartCheck(); this.connectCallBack?.(); // console.log('WebSocket登录成功'); break; case 1: // 心跳响应 this.resetHeartCheck(); break; default: // 其他消息 // console.log("接收到消息", message); if (this.messageCallBack) { this.messageCallBack(message.cmd, message.data); } break; } } // 处理连接关闭 handleClose(res) { this.isConnect = false; this.clearHeartCheck(); if (this.closeCallBack) { this.closeCallBack(res); } } // 重新连接 reconnect(wsurl, token) { console.log("尝试重新连接"); if (this.isConnect) return; const timeDiff = new Date().getTime() - this.lastConnectTime.getTime(); const delay = timeDiff < 10000 ? 10000 - timeDiff : 0; if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); } this.reconnectTimer = setTimeout(() => { this.connect(wsurl, token); }, delay); } // 安排重新连接 scheduleReconnect(wsurl, token) { setTimeout(() => { this.reconnect(wsurl, token); }, 10000); } // 关闭连接 close(code = 1000) { if (!this.isConnect || !this.socketTask) return; this.clearHeartCheck(); this.socketTask.close({ code: code, complete: () => { this.isConnect = false; // console.log("关闭WebSocket连接"); }, fail: (e) => { console.error("关闭WebSocket连接失败", e); } }); } // 发送消息 sendMessage(message) { if (!this.isConnect || !this.socketTask) { console.warn("WebSocket未连接,无法发送消息"); return; } this.socketTask.send({ data: message }); } // 注册连接成功回调 onConnect(callback) { this.connectCallBack = callback; } // 注册消息接收回调 onMessage(callback) { this.messageCallBack = callback; } // 注册连接关闭回调 onClose(callback) { this.closeCallBack = callback; } // 获取连接状态 getIsConnect() { return this.isConnect; } // 获取最后连接时间 getLastConnectTime() { return this.lastConnectTime; } // 设置心跳间隔 setHeartCheckTimeout(timeout) { this.heartCheckTimeout = timeout; } // 销毁实例 destroy() { this.close(); this.clearHeartCheck(); if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } this.messageCallBack = null; this.closeCallBack = null; this.connectCallBack = null; this.socketTask = null; } } export default WebSocket;