import eventBus from './eventBus.js'; import { messageTypes } from '@/enum/socketMessage.js'; import { encodeMessage, decodeMessage } from './socketMessage.js'; import { $socket_base_url } from '@/api/index.js'; class FYWebSocket extends WebSocket { constructor() { super($socket_base_url); return this; } /** * heartBeatConfig 心跳连接参数 * time: 心跳时间间隔 * timeout: 心跳超时间隔 * reconnect: 断线重连时间间隔 * isReconnect 是否断线重连 */ init(heartBeatConfig, isReconnect) { this.onopen = this.openHandler; // 连接成功后的回调函数 this.onclose = this.closeHandler; // 连接关闭后的回调 函数 this.onmessage = this.messageHandler; // 收到服务器数据后的回调函数 this.onerror = this.errorHandler; // 连接发生错误的回调方法 this.heartBeatConfig = heartBeatConfig; // 心跳连接配置参数 this.isReconnect = isReconnect; // 记录是否断线重连 this.reconnectTimer = null; // 记录断线重连的时间器 this.startHeartBeatTimer = null; // 记录心跳时间器 this.webSocketState = false; // 记录socket连接状态 true为已连接 } // 获取消息 getMessage({ data }) { return decodeMessage(data); } // 发送消息 sendMessage(type, data) { return this.send(encodeMessage(type, data)); } // 连接成功后的回调函数 openHandler() { console.log('====onopen 连接成功===='); // socket状态设置为连接,做为后面的断线重连的拦截器 this.webSocketState = true; // 判断是否启动心跳机制 if (this.heartBeatConfig && this.heartBeatConfig.time) { this.startHeartBeat(this.heartBeatConfig.time); } } // 收到服务器数据后的回调函数 messageHandler(res) { const webSocketMsg = this.getMessage(res); if (!(webSocketMsg && webSocketMsg != null && webSocketMsg != {})) { return; } const type = webSocketMsg.type; const data = webSocketMsg.data switch (type) { case '1': // 后台任务 // 发送事件 eventBus.emit('1', data); console.log('====onmessage 后台任务====', data); break; case '2': // 业务日志 // 发送事件 eventBus.emit('2', data); console.log('====onmessage 业务日志====', data); break; case '0': // 心跳检测 // 将连接状态更新为在线 this.webSocketState = true; eventBus.emit('0', data); console.log('====onmessage 心跳检测====', data); break; } } // 连接关闭后的回调 函数 closeHandler() { console.log('====onclose websocket关闭连接===='); // 设置socket状态为断线 this.webSocketState = false; // 在断开连接时 清除心跳时间器和 断开重连时间器 this.startHeartBeatTimer && clearTimeout(this.startHeartBeatTimer); this.reconnectTimer && clearTimeout(this.reconnectTimer); this.reconnectWebSocket(); } errorHandler() { console.log('====onerror websocket连接出错===='); // 设置socket状态为断线 this.webSocketState = false; // 重新连接 this.reconnectWebSocket(); } // 心跳初始化方法 time:心跳间隔 startHeartBeat(time) { this.startHeartBeatTimer = setTimeout(() => { // 客户端每隔一段时间向服务端发送一个心跳消息 this.sendMessage(messageTypes[0].value, Date.now()); this.waitingServer(); }, time); } //在客户端发送消息之后,延时等待服务器响应,通过webSocketState判断是否连线成功 waitingServer() { this.webSocketState = false; setTimeout(() => { // 连线成功状态下 继续心跳检测 if (this.webSocketState) { this.startHeartBeat(this.heartBeatConfig.time); return; } console.log('心跳无响应, 已经和服务端断线'); // 重新连接时,记得要先关闭当前连接 try { this.close(); } catch (error) { console.log('当前连接已经关闭'); } // // 重新连接 // this.reconnectWebSocket() }, this.heartBeatConfig.timeout); } // 重新连接 reconnectWebSocket() { // 判断是否是重新连接状态(即被动状态断线),如果是主动断线的不需要重新连接 if (!this.isReconnect) { return; } // 根据传入的断线重连时间间隔 延时连接 this.reconnectTimer = setTimeout(() => { // 触发重新连接事件 eventBus.emit('reconnect'); }, this.heartBeatConfig.reconnect); } } export { FYWebSocket };