From 2ddaf0e6f7768307d1641388867a1ae448ecd66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chsc=E2=80=9D?= <“huangsucan@kaiyili-lab.com”> Date: Thu, 10 Sep 2026 14:27:39 +0800 Subject: [PATCH] =?UTF-8?q?P2:=20DeviceHealthMonitor=20=E9=87=8D=E8=BF=9E?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=87=E6=95=B0=E9=80=80=E9=81=BF=E7=AD=96?= =?UTF-8?q?=E7=95=A5=EF=BC=883=E2=86=925=E2=86=927=E2=86=92...=E2=86=9215?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UIShare/GlobalVariable/DeviceHealthMonitor.cs | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/UIShare/GlobalVariable/DeviceHealthMonitor.cs b/UIShare/GlobalVariable/DeviceHealthMonitor.cs index 01b1513..573610e 100644 --- a/UIShare/GlobalVariable/DeviceHealthMonitor.cs +++ b/UIShare/GlobalVariable/DeviceHealthMonitor.cs @@ -34,8 +34,14 @@ namespace UIShare.GlobalVariable /// 每个设备的连续失败计数 private readonly ConcurrentDictionary _failureCounts = new(); - /// 连续失败次数阈值,达到后触发重连 - private const int FailureThreshold = 3; + /// 每个设备的重连尝试次数(用于计算退避阈值) + private readonly ConcurrentDictionary _reconnectAttempts = new(); + + /// 基础失败阈值(首次重连触发值) + private const int BaseFailureThreshold = 3; + + /// 退避上限(最大阈值) + private const int MaxBackoffThreshold = 15; /// 健康检查间隔(毫秒) private readonly int _checkIntervalMs; @@ -73,7 +79,7 @@ namespace UIShare.GlobalVariable null, TimeSpan.FromSeconds(10), // 首次检查延迟 10 秒,避免启动时设备尚未连接完成 TimeSpan.FromMilliseconds(_checkIntervalMs)); - LoggerHelper.Info($"[{_scopeName}] 设备健康监控已启动,检查间隔={_checkIntervalMs}ms,重连阈值={FailureThreshold}次"); + LoggerHelper.Info($"[{_scopeName}] 设备健康监控已启动,检查间隔={_checkIntervalMs}ms,基础重连阈值={BaseFailureThreshold}次(指数退避上限={MaxBackoffThreshold})"); } } @@ -86,6 +92,7 @@ namespace UIShare.GlobalVariable _healthCheckTimer?.Dispose(); _healthCheckTimer = null; _failureCounts.Clear(); + _reconnectAttempts.Clear(); } } @@ -119,18 +126,23 @@ namespace UIShare.GlobalVariable if (alive) { - // 连接正常:清零失败计数 + // 连接正常:清零失败计数与退避 _failureCounts.TryRemove(deviceName, out _); + _reconnectAttempts.TryRemove(deviceName, out _); continue; } // 连接断开:累加失败计数 int failures = _failureCounts.AddOrUpdate(deviceName, 1, (_, count) => count + 1); - if (failures < FailureThreshold) + // 计算当前退避阈值:基础值 + 重连尝试次数 × 2,上限为 MaxBackoffThreshold + int attempts = _reconnectAttempts.GetOrAdd(deviceName, 0); + int currentThreshold = Math.Min(BaseFailureThreshold + attempts * 2, MaxBackoffThreshold); + + if (failures < currentThreshold) { LoggerHelper.Warn( - $"[{_scopeName}] 设备 [{deviceName}] 连接断开,等待重连中 ({failures}/{FailureThreshold})"); + $"[{_scopeName}] 设备 [{deviceName}] 连接断开,等待重连中 ({failures}/{currentThreshold})"); continue; } @@ -175,7 +187,9 @@ namespace UIShare.GlobalVariable { try { - LoggerHelper.Info($"[{_scopeName}] 设备 [{deviceName}] 连续 {FailureThreshold} 次检测断连,开始重连..."); + int attempts = _reconnectAttempts.AddOrUpdate(deviceName, 1, (_, c) => c + 1); + int nextThreshold = Math.Min(BaseFailureThreshold + attempts * 2, MaxBackoffThreshold); + LoggerHelper.Info($"[{_scopeName}] 设备 [{deviceName}] 连续失败触发重连(第 {attempts} 次重连,下次阈值={nextThreshold})..."); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); bool ok = await device.ConnectAsync(cts.Token); @@ -186,6 +200,7 @@ namespace UIShare.GlobalVariable if (ok) { _failureCounts.TryRemove(deviceName, out _); + _reconnectAttempts.TryRemove(deviceName, out _); LoggerHelper.Info($"[{_scopeName}] 设备 [{deviceName}] 重连成功"); } else