import { getByValue } 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: 断线重连时间间隔
|
* reconnectFunc 断线重连函数
|
* messageManager 消息管理器
|
*/
|
init(reconnectFunc, messageManager) {
|
this.onopen = this.openHandler; // 连接成功后的回调函数
|
this.onclose = this.closeHandler; // 连接关闭后的回调 函数
|
this.onmessage = this.messageHandler; // 收到服务器数据后的回调函数
|
this.onerror = this.errorHandler; // 连接发生错误的回调方法
|
this.heartBeatConfig = {
|
time: 30 * 1000,
|
timeout: 2 * 1000,
|
reconnect: 30 * 1000
|
}; // 心跳连接配置参数
|
this.isReconnect = typeof reconnectFunc === 'function'; // 记录是否断线重连
|
this.reconnectFunc = reconnectFunc; // 断线重连函数
|
this.messageManager = messageManager; // 消息处理管理器
|
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 websocket连接成功====');
|
// 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;
|
let typeObj = getByValue(type);
|
if (type == 0) {
|
// 将连接状态更新为在线
|
this.webSocketState = true;
|
console.log('====onmessage websocket心跳检测====', data);
|
} else {
|
// 发送事件
|
this.messageManager.emit(typeObj.name, data);
|
console.log(`====onmessage websocket${typeObj.label}====`, data);
|
}
|
}
|
// 连接关闭后的回调 函数
|
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('0', Date.now());
|
this.waitingServer();
|
}, time);
|
}
|
//在客户端发送消息之后,延时等待服务器响应,通过webSocketState判断是否连线成功
|
waitingServer() {
|
this.webSocketState = false;
|
setTimeout(() => {
|
// 连线成功状态下 继续心跳检测
|
if (this.webSocketState) {
|
this.startHeartBeat(this.heartBeatConfig.time);
|
return;
|
}
|
console.log('websocket 心跳无响应, 已经和服务端断线');
|
// 重新连接时,记得要先关闭当前连接
|
try {
|
this.close();
|
} catch (error) {
|
console.log('websocket 当前连接已经关闭');
|
}
|
// // 重新连接
|
// this.reconnectWebSocket()
|
}, this.heartBeatConfig.timeout);
|
}
|
|
// 重新连接
|
reconnectWebSocket() {
|
// 判断是否是重新连接状态(即被动状态断线),如果是主动断线的不需要重新连接
|
if (!this.isReconnect) {
|
return;
|
}
|
// 根据传入的断线重连时间间隔 延时连接
|
this.reconnectTimer = setTimeout(() => {
|
// 触发重新连接函数
|
console.log('====onerror websocket尝试重连====');
|
this.reconnectFunc();
|
}, this.heartBeatConfig.reconnect);
|
}
|
}
|
export { FYWebSocket };
|