first commit

This commit is contained in:
Ls
2026-02-12 12:19:20 +08:00
commit 219fd9be5c
529 changed files with 169918 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
// src/Service/Im/WebSocket.ts
import { EventHandler } from '@/Service/Comm/EventHandler';
import { Service, ImConnectService } from '@/Service/Im/ImConnectService';
class WebSocketManager {
private socketTask: UniApp.SocketTask | null = null;
private heartbeatInterval: ReturnType<typeof setInterval> | null = null;
private readonly heartbeat: number = 30000; // 建议心跳30秒
private isConnecting: boolean = false; // 连接状态锁
private isUserClose: boolean = false; // 是否是用户主动关闭
public ConnectSocketInit(): void {
if (this.isConnecting || this.socketTask) {
console.warn('WebSocket 正在连接或已连接,请勿重复调用。');
return;
}
this.isConnecting = true;
this.isUserClose = false;
ImConnectService.GetConnect().then((res: any) => {
if (res.code !== 0) {
this.isConnecting = false;
// Service.Msg('获取连接地址失败');
return;
}
Service.SetUserClientId(res.data.websocketId);
this.socketTask = uni.connectSocket({
url: res.data.server,
header: { 'content-type': 'application/json' },
// 推荐在小程序端开启 BSON
// #ifdef MP-WEIXIN
// protocols: ['bson'],
// #endif
success: () => {}, // success回调仅表示任务创建成功
});
// ✅ 绑定事件监听 (在 onOpen 外部)
this.socketTask.onOpen(() => {
console.log('==============WebSocket连接正常=============');
this.isConnecting = false;
this.startHeartbeat();
EventHandler.ConnectBus();
});
this.socketTask.onMessage((data: any) => {
console.log('接收到消息');
EventHandler.Events(data);
});
this.socketTask.onClose((e: any) => {
console.log('========WebSocket连接已被关闭========', e);
this.isConnecting = false;
this.stopHeartbeat();
this.socketTask = null; // 清理实例
// 如果不是用户主动关闭,则触发重连
if (!this.isUserClose) {
this.reconnect();
}
});
this.socketTask.onError((err: any) => {
console.error('========WebSocket连接发生错误========', err);
this.isConnecting = false;
// 错误发生时,通常也会触发 onClose由 onClose 统一处理重连
});
}).catch(err => {
this.isConnecting = false;
console.error('GetConnect API 请求失败:', err);
});
}
private startHeartbeat(): void {
this.stopHeartbeat(); // 先停止旧的,确保只有一个
const heartbeatData = JSON.stringify({ code: 'Heart', method: 'Heart' });
this.heartbeatInterval = setInterval(() => {
console.log('======发送心跳检测======');
this.send(heartbeatData);
}, this.heartbeat);
}
private stopHeartbeat(): void {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval);
this.heartbeatInterval = null;
}
}
// 重新连接 (带延迟和重试次数)
public reconnect(): void {
console.log('准备在3秒后尝试重连...');
setTimeout(() => {
console.log('正在尝试重连...');
this.ConnectSocketInit();
// 在您的 EventHandler 或全局事件总线中可以增加重试次数限制
uni.$emit('ImReconnecting');
}, 3000); // 延迟3秒重连避免频繁请求
}
public CloseSocket(reason: string = 'user close'): void {
if (!this.socketTask) return;
this.isUserClose = true;
this.stopHeartbeat(); // ✅ 立即停止心跳
this.socketTask.close({
code: 1000,
reason: reason,
success: () => { // ✅ 使用箭头函数
console.log('===============关闭 WebSocket 成功===================');
},
fail: (err) => { // ✅ 使用箭头函数
console.log('===================关闭 WebSocket 失败=====================', err);
}
});
}
public send(value: any): void {
if (this.socketTask && this.socketTask.readyState === 1) { // 检查连接状态
this.socketTask.send({
data: value,
success: () => {}, // ✅ 使用箭头函数
fail: (err) => { // ✅ 使用箭头函数
console.error('发送消息失败:', err);
// 发送失败通常意味着连接已断开onClose会处理重连
}
});
} else {
console.error('WebSocket 未连接,无法发送消息。');
// 可以考虑将消息放入一个队列,等重连成功后再发送
}
}
}
// 导出单例模式
export const WebSocket = new WebSocketManager();