接线图角落弹框
This commit is contained in:
214
src/utils/webSocketClient.ts
Normal file
214
src/utils/webSocketClient.ts
Normal file
@@ -0,0 +1,214 @@
|
||||
import { ElMessage, EVENT_CODE } from "element-plus";
|
||||
|
||||
// 定义消息类型,用于类型检查
|
||||
type MessageType = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export default class SocketService {
|
||||
// 单例模式实例
|
||||
private static instance: SocketService | null = null;
|
||||
// 和服务端连接的socket对象
|
||||
private ws: WebSocket | null = null;
|
||||
// 存储回调函数
|
||||
private callBackMapping: {
|
||||
[key: string]: ((message: MessageType) => void) | null;
|
||||
} = {};
|
||||
// 标识是否连接成功
|
||||
private connected: boolean = false;
|
||||
// 记录重试的次数
|
||||
private sendRetryCount: number = 0;
|
||||
// 重新连接尝试的次数
|
||||
private connectRetryCount: number = 0;
|
||||
// Web Worker 实例
|
||||
private work: Worker | null = null;
|
||||
// 临时的 Blob URL
|
||||
private workerBlobUrl: string | null = null;
|
||||
// 上次活动时间戳
|
||||
private lastActivityTime: number = 0;
|
||||
// 最后一次收到心跳回复时间
|
||||
private lastResponseHeartTime: number = Date.now();
|
||||
// 重新连接延迟,单位毫秒
|
||||
private reconnectDelay: number = 5000;
|
||||
|
||||
// 单例模式获取实例
|
||||
public static get Instance(): SocketService {
|
||||
if (!this.instance) {
|
||||
this.instance = new SocketService();
|
||||
}
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
// 定义连接服务器的方法
|
||||
public async connect(id: any) {
|
||||
if (!window.WebSocket) {
|
||||
console.log("您的浏览器不支持WebSocket");
|
||||
return;
|
||||
}
|
||||
let response = null;
|
||||
if (import.meta.env.VITE_NAME == "beijing") {
|
||||
response = await fetch("/vue/");
|
||||
} else if (import.meta.env.VITE_NAME == "wuxi") {
|
||||
response = await fetch("");
|
||||
}
|
||||
// const response = await fetch("/vue/");
|
||||
|
||||
const mqttUrl = response.headers.get("X-Mqtt-Url");
|
||||
console.log("🚀 ~ SocketService ~ connect ~ mqttUrl:", mqttUrl);
|
||||
setTimeout(() => {
|
||||
//"ws://10.156.193.182:18093/ws/screen" 北京
|
||||
//"ws://192.168.1.130:19001/ws/askRealTimeData/" 无锡
|
||||
const url = (mqttUrl || "ws://192.168.1.127:19001/ws/") + id;
|
||||
// const url = (mqttUrl || "ws://192.168.1.63:18093/ws/screen") + id;
|
||||
console.log("🚀 ~ SocketService ~ connect ~ url:", url);
|
||||
this.ws = new WebSocket(url);
|
||||
|
||||
this.ws.onopen = () => this.handleOpen();
|
||||
this.ws.onclose = () => this.handleClose();
|
||||
this.ws.onerror = () => this.handleError();
|
||||
this.ws.onmessage = (event) => this.handleMessage(event);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// 处理连接成功事件
|
||||
private handleOpen(): void {
|
||||
ElMessage.success("webSocket连接服务端成功了");
|
||||
console.log("连接服务端成功了");
|
||||
this.connected = true;
|
||||
this.connectRetryCount = 0;
|
||||
this.updateLastActivityTime();
|
||||
this.startHeartbeat();
|
||||
}
|
||||
|
||||
// 处理连接关闭事件
|
||||
private handleClose(): void {
|
||||
console.log("连接webSocket服务端关闭");
|
||||
this.connected = false;
|
||||
this.connectRetryCount++;
|
||||
this.clearHeartbeat();
|
||||
// 可根据需要添加重连逻辑
|
||||
// setTimeout(() => this.connect(), 500 * this.connectRetryCount);
|
||||
}
|
||||
|
||||
// 处理连接错误事件
|
||||
private handleError(): void {
|
||||
ElMessage.error("webSocket连接异常!");
|
||||
}
|
||||
|
||||
// 处理服务端发送过来的数据
|
||||
private handleMessage(event: MessageEvent): void {
|
||||
// console.log('🚀 ~ SocketService ~ handleMessage ~ event.data:', event.data)
|
||||
|
||||
if (event.data == "连接成功") {
|
||||
this.sendHeartbeat();
|
||||
} else if (event.data.length > 10) {
|
||||
let message: MessageType;
|
||||
try {
|
||||
// console.log(
|
||||
// 'Received message:', event.data)
|
||||
message = JSON.parse(event.data);
|
||||
this.callBackMapping["message"]!(message);
|
||||
} catch (e) {
|
||||
// console.error("消息解析失败", event.data, e);
|
||||
return;
|
||||
}
|
||||
// console.log("🚀 ~ SocketService ~ handleMessage ~ message:", message)
|
||||
|
||||
// this.callBackMapping["message"]!(message);
|
||||
} else {
|
||||
// ElMessage.error(event.data);
|
||||
}
|
||||
}
|
||||
|
||||
// 启动心跳检测
|
||||
private startHeartbeat(): void {
|
||||
this.lastResponseHeartTime = Date.now();
|
||||
const url = window.URL.createObjectURL(
|
||||
new Blob([
|
||||
"(function(e){setInterval(function(){this.postMessage(null)},30000)})()",
|
||||
])
|
||||
);
|
||||
this.workerBlobUrl = url;
|
||||
this.work = new Worker(url);
|
||||
this.work.onmessage = (e) => this.handleWorkerMessage(e);
|
||||
}
|
||||
|
||||
// 处理 Web Worker 消息
|
||||
private handleWorkerMessage(e: MessageEvent): void {
|
||||
// if (this.lastActivityTime - this.lastResponseHeartTime > 30000) {
|
||||
// // 说明已经三轮心跳没收到回复了,关闭检测,提示用户。
|
||||
// // ElMessage.error('业务主体模块发生未知异常,请尝试重新启动!')
|
||||
// this.clearHeartbeat()
|
||||
// return
|
||||
// }
|
||||
// console.log(123);
|
||||
|
||||
this.sendHeartbeat();
|
||||
}
|
||||
|
||||
// 发送心跳消息
|
||||
private sendHeartbeat(): void {
|
||||
// console.log(new Date() + '进入心跳消息发送。。。。。。。。。。。。。')
|
||||
if (this.ws) {
|
||||
this.ws.send("alive");
|
||||
this.updateLastActivityTime();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新活动时间
|
||||
private updateLastActivityTime(): void {
|
||||
this.lastActivityTime = Date.now();
|
||||
}
|
||||
|
||||
// 清除心跳检测
|
||||
private clearHeartbeat(): void {
|
||||
if (this.work) {
|
||||
this.work.terminate();
|
||||
this.work = null;
|
||||
}
|
||||
if (this.workerBlobUrl) {
|
||||
window.URL.revokeObjectURL(this.workerBlobUrl);
|
||||
this.workerBlobUrl = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 回调函数的注册
|
||||
public registerCallBack(
|
||||
socketType: string,
|
||||
callBack: (message: MessageType) => void
|
||||
): void {
|
||||
this.callBackMapping[socketType] = callBack;
|
||||
}
|
||||
|
||||
// 取消某一个回调函数
|
||||
public unRegisterCallBack(socketType: string): void {
|
||||
this.callBackMapping[socketType] = null;
|
||||
}
|
||||
|
||||
// 发送数据的方法
|
||||
public send(data: any): void {
|
||||
if (this.connected) {
|
||||
this.sendRetryCount = 0;
|
||||
try {
|
||||
if (this.ws) {
|
||||
this.ws.send(JSON.stringify(data));
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.ws) {
|
||||
this.ws.send(data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.sendRetryCount++;
|
||||
setTimeout(() => this.send(data), this.sendRetryCount * 500);
|
||||
}
|
||||
}
|
||||
|
||||
// 断开方法
|
||||
public closeWs(): void {
|
||||
if (this.connected && this.ws) {
|
||||
this.ws.close();
|
||||
}
|
||||
console.log("执行WS关闭命令..");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user