update
This commit is contained in:
@@ -20,8 +20,13 @@ class ClientCore {
|
||||
bool _isConnected = false;
|
||||
DateTime? _lastPingTime;
|
||||
Timer? _heartbeatTimer;
|
||||
Timer? _reconnectTimer;
|
||||
StreamController<String>? _logController;
|
||||
|
||||
// 重连相关
|
||||
int _reconnectAttempts = 0;
|
||||
static const int _maxReconnectAttempts = 5;
|
||||
|
||||
// 需要GPU和挖矿软件信息用于认证
|
||||
Map<String, dynamic>? _gpusInfo;
|
||||
List<String>? _miningSofts;
|
||||
@@ -86,11 +91,10 @@ class ClientCore {
|
||||
|
||||
_socket = await Socket.connect(host, port, timeout: const Duration(seconds: 10));
|
||||
_isConnected = true;
|
||||
// 连接成功,重置重连计数器
|
||||
_reconnectAttempts = 0;
|
||||
_log('连接到服务器成功: $_serverUrl');
|
||||
|
||||
// 注意:不在这里发送身份认证,等待机器码获取完成后再发送
|
||||
// 身份认证消息将在机器码获取完成后通过 sendMachineCode() 发送
|
||||
|
||||
// 开始接收消息
|
||||
_socket!.listen(
|
||||
_onDataReceived,
|
||||
@@ -100,6 +104,12 @@ class ClientCore {
|
||||
);
|
||||
|
||||
onStatusChanged?.call(ui.ClientStatus.online);
|
||||
|
||||
// 如果已经有机器码和认证信息,立即发送认证消息(重连场景)
|
||||
if (_auth != null && _machineCode != null && _machineCode!.isNotEmpty && _machineCode != '正在获取...' && _machineCode != '获取失败') {
|
||||
_log('重连成功,自动发送身份认证消息');
|
||||
_sendMachineCode();
|
||||
}
|
||||
} catch (e) {
|
||||
_isConnected = false;
|
||||
_log('连接失败: $e');
|
||||
@@ -280,20 +290,54 @@ class ClientCore {
|
||||
_reconnect();
|
||||
}
|
||||
|
||||
/// 重连
|
||||
/// 重连(指数退避策略)
|
||||
void _reconnect() {
|
||||
Future.delayed(const Duration(seconds: 5), () {
|
||||
// 检查是否正在停止或已停止
|
||||
// 取消之前的重连定时器
|
||||
_reconnectTimer?.cancel();
|
||||
|
||||
// 检查是否正在停止或已停止
|
||||
if (_socket == null || _logController == null) {
|
||||
return; // 已经停止,不执行重连
|
||||
}
|
||||
|
||||
// 检查是否已达到最大重试次数
|
||||
if (_reconnectAttempts >= _maxReconnectAttempts) {
|
||||
_log('已达到最大重连次数($_maxReconnectAttempts次),停止重连');
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算延迟时间:10秒 * 2^(重试次数)
|
||||
// 第1次:10秒,第2次:20秒,第3次:40秒,第4次:80秒,第5次:160秒
|
||||
final delaySeconds = 10 * (1 << _reconnectAttempts);
|
||||
_reconnectAttempts++;
|
||||
|
||||
_log('将在 ${delaySeconds}秒 后进行第 $_reconnectAttempts 次重连尝试(最多$_maxReconnectAttempts次)');
|
||||
|
||||
_reconnectTimer = Timer(Duration(seconds: delaySeconds), () {
|
||||
// 再次检查是否正在停止或已停止
|
||||
if (_socket == null || _logController == null) {
|
||||
return; // 已经停止,不执行重连
|
||||
}
|
||||
|
||||
if (!_isConnected) {
|
||||
_log('尝试重新连接...');
|
||||
_connect().catchError((e) {
|
||||
_log('重连失败: $e');
|
||||
});
|
||||
// 检查是否已经连接成功(可能在其他地方已经连接)
|
||||
if (_isConnected) {
|
||||
_reconnectAttempts = 0; // 重置计数器
|
||||
return;
|
||||
}
|
||||
|
||||
_log('尝试第 $_reconnectAttempts 次重新连接...');
|
||||
_connect().then((_) {
|
||||
// 连接成功,计数器已在 _connect() 中重置
|
||||
_log('重连成功');
|
||||
}).catchError((e) {
|
||||
_log('第 $_reconnectAttempts 次重连失败: $e');
|
||||
// 如果未达到最大重试次数,继续重连
|
||||
if (_reconnectAttempts < _maxReconnectAttempts) {
|
||||
_reconnect();
|
||||
} else {
|
||||
_log('已达到最大重连次数,停止重连');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -307,6 +351,8 @@ class ClientCore {
|
||||
_log('超过60分钟未收到心跳,连接可能已断开');
|
||||
_isConnected = false;
|
||||
onStatusChanged?.call(ui.ClientStatus.offline);
|
||||
// 心跳超时视为新的断开事件,重置重连计数器
|
||||
_reconnectAttempts = 0;
|
||||
_reconnect();
|
||||
}
|
||||
}
|
||||
@@ -331,6 +377,10 @@ class ClientCore {
|
||||
_heartbeatTimer?.cancel();
|
||||
_heartbeatTimer = null;
|
||||
|
||||
_reconnectTimer?.cancel();
|
||||
_reconnectTimer = null;
|
||||
_reconnectAttempts = 0; // 重置重连计数器
|
||||
|
||||
// 先取消 socket 监听,避免 onDone 回调在关闭 controller 后执行
|
||||
_socket?.destroy();
|
||||
_socket = null;
|
||||
|
||||
Reference in New Issue
Block a user