Files
pqs-9100_client/frontend/src/utils/webSocketClient.ts

178 lines
5.0 KiB
TypeScript
Raw Normal View History

2024-12-20 16:32:03 +08:00
import {ElMessage} from "element-plus";
2024-12-20 16:32:03 +08:00
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;
2025-01-16 15:57:29 +08:00
heartbeatTimer;
lastActivityTime= 0; // 上次活动时间戳
2025-02-18 14:59:13 +08:00
lastResponseHeartTime = Date.now();//最后一次收到心跳回复时间
2025-01-16 15:57:29 +08:00
reconnectDelay= 5000; // 重新连接延迟,单位毫秒
2024-12-20 16:32:03 +08:00
// 定义连接服务器的方法
2025-01-17 09:14:19 +08:00
connect() {
2024-12-20 16:32:03 +08:00
// 连接服务器
if (!window.WebSocket) {
return console.log('您的浏览器不支持WebSocket');
}
2025-01-17 09:14:19 +08:00
2024-12-20 16:32:03 +08:00
// let token = $.cookie('123');
// let token = '4E6EF539AAF119D82AC4C2BC84FBA21F';
2025-01-22 12:09:32 +08:00
const url = 'ws://localhost:7777/hello?name=cdf'
2024-12-20 16:32:03 +08:00
this.ws = new WebSocket(url);
// 连接成功的事件
this.ws.onopen = () => {
ElMessage.success("webSocket连接服务端成功了");
console.log('连接服务端成功了');
this.connected = true;
// 重置重新连接的次数
this.connectRetryCount = 0;
2025-01-16 15:57:29 +08:00
this.updateLastActivityTime();
this.startHeartbeat();
2024-12-20 16:32:03 +08:00
};
// 1.连接服务端失败
// 2.当连接成功之后, 服务器关闭的情况
this.ws.onclose = () => {
console.log('连接服务端失败');
this.connected = false;
this.connectRetryCount++;
2025-01-16 15:57:29 +08:00
this.clearHeartbeat();
2025-02-18 14:59:13 +08:00
/* setTimeout(() => {
this.connect();
}, 500 * this.connectRetryCount);*/
2025-01-16 15:57:29 +08:00
2024-12-20 16:32:03 +08:00
};
2025-01-17 09:14:19 +08:00
this.ws.onerror = () => {
ElMessage.error("webSocket连接异常");
};
2025-02-18 14:59:13 +08:00
2024-12-20 16:32:03 +08:00
// 得到服务端发送过来的数据
this.ws.onmessage = (event) => {
2025-02-18 14:59:13 +08:00
if(event.data == 'over') {
//心跳消息处理
this.lastResponseHeartTime = Date.now();
}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 {
2025-01-16 15:57:29 +08:00
console.log("抛弃====>")
console.log(event.data)
/* 丢弃或继续写你的逻辑 */
2025-02-18 14:59:13 +08:00
}
2024-12-20 16:32:03 +08:00
}
2025-02-18 14:59:13 +08:00
2024-12-20 16:32:03 +08:00
};
}
2025-01-16 15:57:29 +08:00
startHeartbeat() {
2025-02-18 14:59:13 +08:00
const _this = this
const url = window.URL.createObjectURL(new Blob(['(function(e){setInterval(function(){this.postMessage(null)},10000)})()']));
this.work = new Worker(url)
this.work.onmessage = function(e){
2025-02-18 14:59:13 +08:00
//判断多久没收到心跳响应
if(_this.lastActivityTime - _this.lastResponseHeartTime > 30000){
//说明已经三轮心跳没收到回复了,关闭检测,提示用户。
ElMessage.error("业务主体模块发生未知异常,请尝试重新启动!");
return;
2025-01-16 15:57:29 +08:00
}
2025-02-18 14:59:13 +08:00
_this.sendHeartbeat();
}
2025-02-18 14:59:13 +08:00
2025-01-16 15:57:29 +08:00
}
sendHeartbeat() {
2025-02-18 14:59:13 +08:00
console.log(new Date()+"进入心跳消息发送。。。。。。。。。。。。。")
2025-01-16 15:57:29 +08:00
this.ws.send('alive');
this.updateLastActivityTime(); // 发送心跳后更新活动时间
}
updateLastActivityTime() {
this.lastActivityTime = Date.now();
}
clearHeartbeat() {
this.work.terminate();
2025-01-16 15:57:29 +08:00
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
2024-12-20 16:32:03 +08:00
// 回调函数的注册
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关闭中..');
}
}