Files
sgxt_web/src/utils/webSocket.js

203 lines
5.8 KiB
JavaScript
Raw Normal View History

2025-12-18 17:18:53 +08:00
let url = "ws://89.40.9.89:2109/mosty-api/mosty-websocket/socket/"; //线上
if(process.env.NODE_ENV === 'development') {
url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地
}
2025-04-12 14:54:02 +08:00
import {
getItem
} from "@/utils/storage";
2025-11-27 14:27:59 +08:00
import emitter from "@/utils/eventBus.js"; // 导入事件总线
2025-04-12 14:54:02 +08:00
class WebSoketClass {
2025-11-27 14:27:59 +08:00
constructor(props) {
this.ws = null;
this.state = null;
this.reconnectCount = 0;
this.maxReconnectCount = 10;
this.reconnectInterval = 6000;
this.uuid = null; // 保存UUID用于重连时复用
this.sfzh = null; // 保存身份证号,用于重连时复用
this.fullUrl = null; // 保存完整连接URL用于重连时复用
}
2025-04-12 14:54:02 +08:00
static getInstance() {
2025-11-27 14:27:59 +08:00
if (!this.instance) this.instance = new WebSoketClass();
return this.instance;
2025-04-12 14:54:02 +08:00
}
2025-11-27 14:27:59 +08:00
2025-04-12 14:54:02 +08:00
//关闭连接
static close() {
2025-11-27 14:27:59 +08:00
if (this.instance) {
this.instance.closeConnection();
}
2025-04-12 14:54:02 +08:00
}
2025-11-27 14:27:59 +08:00
// 关闭连接的实例方法
closeConnection() {
if (this.ws) {
this.ws.close();
this.ws = null;
}
if (this.state) {
clearInterval(this.state);
this.state = null;
}
this.reconnectCount = 0;
// 重置UUID下次连接时生成新的
this.uuid = null;
this.fullUrl = null;
}
2025-04-12 14:54:02 +08:00
// 创建连接
connect(fun) {
2025-11-27 14:27:59 +08:00
// 首次连接时获取并保存连接参数
if (!this.sfzh) {
this.sfzh = getItem("idEntityCard");
}
// 首次连接时生成并保存UUID
if (!this.uuid) {
this.uuid = this.getUUid();
}
if (this.sfzh) {
try {
// 如果还没有完整URL或需要更新重新构建
if (!this.fullUrl || this.maxReconnectCount == 10) {
this.fullUrl = url + this.sfzh + '/' + this.uuid;
this.reconnectCount = 0;
}
console.log('尝试连接WebSocket:', this.fullUrl);
this.ws = new WebSocket(this.fullUrl);
console.log(this.ws);
this.ws.onopen = (e) => {
console.log('WebSocket连接已打开');
// 只有在非重连状态下才重置重连计数
// 避免短暂连接成功后又关闭导致计数重置
if (this.reconnectCount === 0) {
console.log('首次连接成功');
} else {
console.log('重连成功');
// 重连成功后重置计数
// this.reconnectCount = 0;
}
this.heartCheck();
this.getMessage();
if (fun) fun(true);
};
this.ws.onclose = (e) => {
console.log(e);
console.log('WebSocket连接已关闭关闭码:', e.code, '原因:', e.reason);
// 如果是正常关闭(1000)或手动关闭(1001),不进行重连
if (e.code !== 1000 && e.code !== 1001) {
this.handleReconnect(fun);
} else {
console.log('WebSocket正常关闭不进行重连');
}
};
this.ws.onerror = (e) => {
console.error('WebSocket连接错误:', e);
this.handleReconnect(fun);
};
} catch (error) {
console.error('创建WebSocket连接失败:', error);
this.handleReconnect(fun);
}
} else {
console.error('获取用户身份证号失败无法建立WebSocket连接');
if (fun) fun(false);
}
2025-04-12 14:54:02 +08:00
}
// 心跳机制
heartCheck() {
2025-11-27 14:27:59 +08:00
if (this.state) {
clearInterval(this.state);
}
2025-04-12 14:54:02 +08:00
this.state = setInterval(() => {
2025-11-27 14:27:59 +08:00
try {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send("/heart");
} else {
console.log('WebSocket未连接停止心跳');
clearInterval(this.state);
this.state = null;
}
} catch (error) {
console.error('心跳发送失败:', error);
clearInterval(this.state);
this.state = null;
2025-04-12 14:54:02 +08:00
}
2025-11-27 14:27:59 +08:00
}, 6000);
2025-04-12 14:54:02 +08:00
}
// 获取uuid
getUUid() {
var s = [];
var hexDigits = "0123456789abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < 32; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23];
let uuid = s.join("");
return uuid
}
2025-11-27 14:27:59 +08:00
// 处理重连
handleReconnect(fun) {
if (this.reconnectCount >= this.maxReconnectCount) {
console.log('达到最大重连次数,停止重连');
if (fun) fun(false);
return;
2025-04-12 14:54:02 +08:00
}
2025-11-27 14:27:59 +08:00
this.reconnectCount++;
console.log(`尝试第${this.reconnectCount}次重连...`);
setTimeout(() => {
this.connect(fun);
}, this.reconnectInterval);
2025-04-12 14:54:02 +08:00
}
// 接收发送消息
getMessage() {
this.ws.onmessage = (e) => {
2025-11-27 14:27:59 +08:00
console.log(e);
try {
if (e.data) {
let newsDate = JSON.parse(e.data);
// 根据消息类型发射相应的事件
if (newsDate.type === '01') {
// 触发音频播放
console.log('触发音频播放');
emitter.emit('openYp', newsDate.data); // 传递消息数据
}
// else if (newsDate.type === 'ALARM_STOP' || newsDate.type === 'warning_stop') {
// // 触发音频停止
// emitter.emit('closeYp');
// } else if (newsDate.type === 'POSITION_UPDATE') {
// // 位置更新事件
// emitter.emit('positionUpdate', newsDate.data);
// } else if (newsDate.type === 'STATUS_UPDATE') {
// // 状态更新事件
// emitter.emit('statusUpdate', newsDate.data);
// }
// // 通用消息事件
// emitter.emit('webSocketMessage', newsDate);
}
} catch (error) {
console.error('处理WebSocket消息失败:', error);
// 如果是心跳响应,不报错
if (e.data !== '/heart') {
console.error('消息内容:', e.data);
}
2025-04-12 14:54:02 +08:00
}
};
}
}
export default WebSoketClass;