179 lines
5.2 KiB
TypeScript
179 lines
5.2 KiB
TypeScript
import {ElMessage} from "element-plus";
|
||
|
||
|
||
export default class SocketService {
|
||
static instance = null;
|
||
static get Instance() {
|
||
if (!this.instance) {
|
||
this.instance = new SocketService();
|
||
}
|
||
return this.instance;
|
||
}
|
||
// 和服务端连接的socket对象
|
||
ws = null;
|
||
// 存储回调函数
|
||
callBackMapping = {};
|
||
// 标识是否连接成功
|
||
connected = false;
|
||
// 记录重试的次数
|
||
sendRetryCount = 0;
|
||
// 重新连接尝试的次数
|
||
connectRetryCount = 0;
|
||
work:any;
|
||
heartbeatTimer;
|
||
lastActivityTime= 0; // 上次活动时间戳
|
||
lastResponseHeartTime = Date.now();//最后一次收到心跳回复时间
|
||
|
||
reconnectDelay= 5000; // 重新连接延迟,单位毫秒
|
||
|
||
// 定义连接服务器的方法
|
||
connect() {
|
||
|
||
// 连接服务器
|
||
if (!window.WebSocket) {
|
||
return console.log('您的浏览器不支持WebSocket');
|
||
}
|
||
|
||
// let token = $.cookie('123');
|
||
// let token = '4E6EF539AAF119D82AC4C2BC84FBA21F';
|
||
|
||
|
||
const url = 'ws://localhost:7777/hello?name=cdf'
|
||
this.ws = new WebSocket(url);
|
||
// 连接成功的事件
|
||
this.ws.onopen = () => {
|
||
ElMessage.success("webSocket连接服务端成功了");
|
||
console.log('连接服务端成功了');
|
||
this.connected = true;
|
||
// 重置重新连接的次数
|
||
this.connectRetryCount = 0;
|
||
this.updateLastActivityTime();
|
||
this.startHeartbeat();
|
||
};
|
||
// 1.连接服务端失败
|
||
// 2.当连接成功之后, 服务器关闭的情况
|
||
this.ws.onclose = () => {
|
||
console.log('连接webSocket服务端关闭');
|
||
this.connected = false;
|
||
this.connectRetryCount++;
|
||
this.clearHeartbeat();
|
||
/* setTimeout(() => {
|
||
this.connect();
|
||
}, 500 * this.connectRetryCount);*/
|
||
|
||
|
||
};
|
||
|
||
this.ws.onerror = () => {
|
||
ElMessage.error("webSocket连接异常!");
|
||
|
||
|
||
};
|
||
|
||
|
||
// 得到服务端发送过来的数据
|
||
this.ws.onmessage = (event) => {
|
||
if(event.data == 'over') {
|
||
//心跳消息处理
|
||
this.lastResponseHeartTime = Date.now();
|
||
this.updateLastActivityTime(); // 收到心跳响应时更新活动时间
|
||
}else {
|
||
let message: { [key: string]: any };
|
||
try {
|
||
console.log('Received message:',event.data)
|
||
message = JSON.parse(event.data);
|
||
} catch (e) {
|
||
return console.error("消息解析失败", event.data, e);
|
||
}
|
||
|
||
/* 通过接受服务端发送的type字段来回调函数 */
|
||
if (message?.type && this.callBackMapping[message.type]) {
|
||
this.callBackMapping[message.type](message);
|
||
} else {
|
||
console.log("抛弃====>")
|
||
console.log(event.data)
|
||
/* 丢弃或继续写你的逻辑 */
|
||
}
|
||
}
|
||
|
||
|
||
};
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
startHeartbeat() {
|
||
const _this = this
|
||
const url = window.URL.createObjectURL(new Blob(['(function(e){setInterval(function(){this.postMessage(null)},9000)})()']));
|
||
this.work = new Worker(url)
|
||
this.work.onmessage = function(e){
|
||
//判断多久没收到心跳响应
|
||
|
||
if(_this.lastActivityTime - _this.lastResponseHeartTime > 30000){
|
||
//说明已经三轮心跳没收到回复了,关闭检测,提示用户。
|
||
ElMessage.error("业务主体模块发生未知异常,请尝试重新启动!");
|
||
_this.clearHeartbeat();
|
||
return;
|
||
}
|
||
_this.sendHeartbeat();
|
||
}
|
||
|
||
}
|
||
sendHeartbeat() {
|
||
console.log(new Date()+"进入心跳消息发送。。。。。。。。。。。。。")
|
||
this.ws.send('alive');
|
||
this.updateLastActivityTime(); // 发送心跳后更新活动时间
|
||
}
|
||
|
||
|
||
updateLastActivityTime() {
|
||
this.lastActivityTime = Date.now();
|
||
}
|
||
|
||
clearHeartbeat() {
|
||
this.work.terminate();
|
||
if (this.heartbeatTimer) {
|
||
clearInterval(this.heartbeatTimer);
|
||
this.heartbeatTimer = null;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// 回调函数的注册
|
||
registerCallBack(socketType, callBack) {
|
||
this.callBackMapping[socketType] = callBack;
|
||
}
|
||
// 取消某一个回调函数
|
||
unRegisterCallBack(socketType) {
|
||
this.callBackMapping[socketType] = null;
|
||
}
|
||
// 发送数据的方法
|
||
send(data) {
|
||
// 判断此时此刻有没有连接成功
|
||
if (this.connected) {
|
||
this.sendRetryCount = 0;
|
||
try {
|
||
this.ws.send(JSON.stringify(data));
|
||
} catch (e) {
|
||
this.ws.send(data);
|
||
}
|
||
} else {
|
||
this.sendRetryCount++;
|
||
setTimeout(() => {
|
||
this.send(data);
|
||
}, this.sendRetryCount * 500);
|
||
}
|
||
}
|
||
|
||
// 断开方法
|
||
closeWs() {
|
||
if (this.connected) {
|
||
this.ws.close()
|
||
}
|
||
console.log('执行WS关闭命令..');
|
||
}
|
||
}
|