using System.Collections.Concurrent; using System.Net.WebSockets; namespace YD_YiLu.Api.WebSockets { public class DeviceConnection { public WebSocket Socket { get; set; } = default!; public DateTime LastHeartbeat { get; set; } = DateTime.Now; } public interface ICameraDeviceSocketRegistry { void Register(string serialNumber, WebSocket socket); void Unregister(string serialNumber); bool TryGet(string serialNumber, out WebSocket socket); void UpdateHeartbeat(string serialNumber); List GetTimeoutDevices(TimeSpan timeout); } public class CameraDeviceSocketRegistry : ICameraDeviceSocketRegistry { private readonly ConcurrentDictionary _connections = new(StringComparer.OrdinalIgnoreCase); public void Register(string serialNumber, WebSocket socket) { _connections[serialNumber] = new DeviceConnection { Socket = socket, LastHeartbeat = DateTime.Now }; } public void Unregister(string serialNumber) { _connections.TryRemove(serialNumber, out _); } public bool TryGet(string serialNumber, out WebSocket socket) { if (_connections.TryGetValue(serialNumber, out var conn)) { socket = conn.Socket; return true; } socket = null!; return false; } public void UpdateHeartbeat(string serialNumber) { if (_connections.TryGetValue(serialNumber, out var conn)) { conn.LastHeartbeat = DateTime.Now; } } public List GetTimeoutDevices(TimeSpan timeout) { var now = DateTime.Now; return _connections .Where(x => now - x.Value.LastHeartbeat > timeout) .Select(x => x.Key) .ToList(); } } }