204 lines
5.9 KiB
JavaScript
204 lines
5.9 KiB
JavaScript
// 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;
|