feat: 修改文件 │
│ │
│ 1. src/services/socketService.js - 指数退避 + 无限重试 │
│ 2. src/components/ConnectionStatusBar/index.js - UI 优化 + 自动消失 │
│ 3. src/App.js - handleClose 实现 + dismissed 状态管理 │
│ 4. src/contexts/NotificationContext.js - 添加成功状态检测 │
│ 5. NOTIFICATION_SYSTEM.md - v2.11.0 文档更新
This commit is contained in:
@@ -14,7 +14,18 @@ class SocketService {
|
||||
this.socket = null;
|
||||
this.connected = false;
|
||||
this.reconnectAttempts = 0;
|
||||
this.maxReconnectAttempts = 5;
|
||||
this.maxReconnectAttempts = Infinity; // 无限重试
|
||||
this.customReconnectTimer = null; // 自定义重连定时器
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指数退避延迟
|
||||
* 第1次: 60秒, 第2次: 120秒, 第3次: 240秒, 第4次及以后: 240秒
|
||||
*/
|
||||
getReconnectionDelay(attempt) {
|
||||
const delays = [60000, 120000, 240000]; // 1min, 2min, 4min
|
||||
const index = Math.min(attempt - 1, delays.length - 1);
|
||||
return delays[index];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,13 +40,10 @@ class SocketService {
|
||||
|
||||
logger.info('socketService', 'Connecting to Socket.IO server...', { url: API_BASE_URL });
|
||||
|
||||
// 创建 socket 连接
|
||||
// 创建 socket 连接 - 禁用 Socket.IO 自带的重连机制,使用自定义指数退避
|
||||
this.socket = io(API_BASE_URL, {
|
||||
transports: ['websocket', 'polling'],
|
||||
reconnection: true,
|
||||
reconnectionDelay: 1000,
|
||||
reconnectionDelayMax: 5000,
|
||||
reconnectionAttempts: this.maxReconnectAttempts,
|
||||
reconnection: false, // 禁用自动重连,改用自定义策略
|
||||
timeout: 20000,
|
||||
autoConnect: true,
|
||||
withCredentials: true, // 允许携带认证信息
|
||||
@@ -46,6 +54,13 @@ class SocketService {
|
||||
this.socket.on('connect', () => {
|
||||
this.connected = true;
|
||||
this.reconnectAttempts = 0;
|
||||
|
||||
// 清除自定义重连定时器
|
||||
if (this.customReconnectTimer) {
|
||||
clearTimeout(this.customReconnectTimer);
|
||||
this.customReconnectTimer = null;
|
||||
}
|
||||
|
||||
logger.info('socketService', 'Socket.IO connected successfully', {
|
||||
socketId: this.socket.id,
|
||||
});
|
||||
@@ -53,8 +68,14 @@ class SocketService {
|
||||
|
||||
// 监听断开连接
|
||||
this.socket.on('disconnect', (reason) => {
|
||||
const wasConnected = this.connected;
|
||||
this.connected = false;
|
||||
logger.warn('socketService', 'Socket.IO disconnected', { reason });
|
||||
|
||||
// 如果是意外断开(非主动断开),触发自定义重连
|
||||
if (wasConnected && reason !== 'io client disconnect') {
|
||||
this.scheduleReconnection();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听连接错误
|
||||
@@ -62,30 +83,33 @@ class SocketService {
|
||||
this.reconnectAttempts++;
|
||||
logger.error('socketService', 'connect_error', error, {
|
||||
attempts: this.reconnectAttempts,
|
||||
maxAttempts: this.maxReconnectAttempts,
|
||||
});
|
||||
|
||||
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
||||
logger.error('socketService', 'Max reconnection attempts reached');
|
||||
this.socket.close();
|
||||
// 使用指数退避策略安排下次重连
|
||||
this.scheduleReconnection();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用指数退避策略安排重连
|
||||
*/
|
||||
scheduleReconnection() {
|
||||
// 清除之前的定时器
|
||||
if (this.customReconnectTimer) {
|
||||
clearTimeout(this.customReconnectTimer);
|
||||
}
|
||||
|
||||
const delay = this.getReconnectionDelay(this.reconnectAttempts);
|
||||
logger.info('socketService', `Scheduling reconnection in ${delay / 1000}s (attempt ${this.reconnectAttempts})`);
|
||||
|
||||
this.customReconnectTimer = setTimeout(() => {
|
||||
if (!this.connected && this.socket) {
|
||||
logger.info('socketService', 'Attempting reconnection...', {
|
||||
attempt: this.reconnectAttempts,
|
||||
});
|
||||
this.socket.connect();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听重连尝试
|
||||
this.socket.io.on('reconnect_attempt', (attemptNumber) => {
|
||||
logger.info('socketService', 'Reconnection attempt', { attemptNumber });
|
||||
});
|
||||
|
||||
// 监听重连成功
|
||||
this.socket.io.on('reconnect', (attemptNumber) => {
|
||||
this.reconnectAttempts = 0;
|
||||
logger.info('socketService', 'Reconnected successfully', { attemptNumber });
|
||||
});
|
||||
|
||||
// 监听重连失败
|
||||
this.socket.io.on('reconnect_failed', () => {
|
||||
logger.error('socketService', 'Reconnection failed after max attempts');
|
||||
});
|
||||
}, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,9 +121,17 @@ class SocketService {
|
||||
}
|
||||
|
||||
logger.info('socketService', 'Disconnecting from Socket.IO server...');
|
||||
|
||||
// 清除自定义重连定时器
|
||||
if (this.customReconnectTimer) {
|
||||
clearTimeout(this.customReconnectTimer);
|
||||
this.customReconnectTimer = null;
|
||||
}
|
||||
|
||||
this.socket.disconnect();
|
||||
this.socket = null;
|
||||
this.connected = false;
|
||||
this.reconnectAttempts = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,10 +236,16 @@ class SocketService {
|
||||
|
||||
logger.info('socketService', 'Manually triggering reconnection...');
|
||||
|
||||
// 清除自动重连定时器
|
||||
if (this.customReconnectTimer) {
|
||||
clearTimeout(this.customReconnectTimer);
|
||||
this.customReconnectTimer = null;
|
||||
}
|
||||
|
||||
// 重置重连计数
|
||||
this.reconnectAttempts = 0;
|
||||
|
||||
// 触发重连
|
||||
// 立即触发重连
|
||||
this.socket.connect();
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user