using System; using Newtonsoft.Json; using System.Globalization; using WingInterfaceLibrary.Enum; using System.Collections.Concurrent; using System.Threading.Tasks; using WingServerCommon.Log; using System.Threading; using WingServerCommon.Utilities.Executors; namespace WingDeviceService.Common { internal class DeviceHeartRateManager { private ConcurrentDictionary _devices = new ConcurrentDictionary(); private Func OnSetOnlineState; Func OnCheckDeviceRoomStatus; public DeviceHeartRateManager(Func setOnlineState, Func checkDeviceRoomStatus) { OnSetOnlineState = setOnlineState; OnCheckDeviceRoomStatus = checkDeviceRoomStatus; StartCheckClients(); } /// /// 加入检测集合 /// /// public void AddOrUpdate(string token) { _devices.AddOrUpdate(token, new DeviceHeartRateDTO(token), (k, v) => { v.Activate(); return v; }); } /// /// 设备心跳有效期验证 /// private void StartCheckClients() { Logger.WriteLineInfo($"DeviceHeartRateManager start check clients"); Task.Run(async () => { while (true) { await Task.Delay(1 * 60 * 1000); foreach (var token in _devices.Keys) { var heartRate = _devices[token]; heartRate.DeActivate(); try { if (heartRate.LeftTime < 0) { OnSetOnlineState?.Invoke(token, false); } } catch (Exception ex) { Logger.WriteLineWarn($"check device token {token} err, {ex}"); } finally { if (heartRate.LeftTime < 0) { _devices.TryRemove(token, out _); } } } OnCheckDeviceRoomStatus?.Invoke(); } }); Logger.WriteLineInfo($"DeviceHeartRateManager finished"); } } internal class DeviceHeartRateDTO { public DeviceHeartRateDTO(string token) { Token = token; } private volatile int _livingTime = 0; private readonly int _clientLifecycle = 10; //10 minutes public string Token { get; set; } public int LeftTime => _clientLifecycle - _livingTime; /// /// Reset the living time. /// public virtual void Activate() { _livingTime = 0; } /// /// Deactive the session. /// public virtual void DeActivate() { _livingTime++; } } }