60 lines
2.0 KiB
C#
60 lines
2.0 KiB
C#
using System.Net.WebSockets;
|
|
|
|
namespace YD_YiLu.Api.WebSockets
|
|
{
|
|
public class DeviceHeartbeatCleanupService : BackgroundService
|
|
{
|
|
private readonly ICameraDeviceSocketRegistry _registry;
|
|
private readonly ILogger<DeviceHeartbeatCleanupService> _logger;
|
|
|
|
public DeviceHeartbeatCleanupService(
|
|
ICameraDeviceSocketRegistry registry,
|
|
ILogger<DeviceHeartbeatCleanupService> logger)
|
|
{
|
|
_registry = registry;
|
|
_logger = logger;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
var interval = TimeSpan.FromSeconds(30); // 每30秒检查
|
|
var timeout = TimeSpan.FromSeconds(90); // 超过90秒算离线
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
var timeoutDevices = _registry.GetTimeoutDevices(timeout);
|
|
|
|
foreach (var sn in timeoutDevices)
|
|
{
|
|
if (_registry.TryGet(sn, out var socket))
|
|
{
|
|
try
|
|
{
|
|
if (socket.State == WebSocketState.Open)
|
|
{
|
|
await socket.CloseAsync(
|
|
WebSocketCloseStatus.NormalClosure,
|
|
"Heartbeat timeout",
|
|
stoppingToken);
|
|
}
|
|
}
|
|
catch { }
|
|
|
|
_registry.Unregister(sn);
|
|
|
|
_logger.LogWarning("⚠️ 设备超时已移除: {0}", sn);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "心跳清理异常");
|
|
}
|
|
|
|
await Task.Delay(interval, stoppingToken);
|
|
}
|
|
}
|
|
}
|
|
} |