Files
sgxt_web/src/utils/webSocket.js
2025-12-26 09:39:22 +08:00

204 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// let url = "ws://89.40.9.89:2109/mosty-api/mosty-websocket/socket/"; //线上
let url = "ws://155.240.22.30:2109/mosty-api/mosty-websocket/socket/"; //线上
if (process.env.NODE_ENV === 'development') {
url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地
}
import {
getItem
} from "@/utils/storage";
import emitter from "@/utils/eventBus.js"; // 导入事件总线
class WebSoketClass {
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用于重连时复用
}
static getInstance() {
if (!this.instance) this.instance = new WebSoketClass();
return this.instance;
}
//关闭连接
static close() {
if (this.instance) {
this.instance.closeConnection();
}
}
// 关闭连接的实例方法
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;
}
// 创建连接
connect(fun) {
// 首次连接时获取并保存连接参数
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);
}
}
// 心跳机制
heartCheck() {
if (this.state) {
clearInterval(this.state);
}
this.state = setInterval(() => {
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;
}
}, 6000);
}
// 获取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
}
// 处理重连
handleReconnect(fun) {
if (this.reconnectCount >= this.maxReconnectCount) {
console.log('达到最大重连次数,停止重连');
if (fun) fun(false);
return;
}
this.reconnectCount++;
console.log(`尝试第${this.reconnectCount}次重连...`);
setTimeout(() => {
this.connect(fun);
}, this.reconnectInterval);
}
// 接收发送消息
getMessage() {
this.ws.onmessage = (e) => {
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);
}
}
};
}
}
export default WebSoketClass;