using Cis.Application.Cb; using Cis.Application.Cm; using Cis.Application.Core.Component.MarkSeacher; using Cis.Application.Core.Component.PtzServer; using EC.Helper.CameraSDK; using StackExchange.Profiling.Internal; using StackExchange.Redis; using System.Collections.Concurrent; namespace Cis.Application.Core; public class CameraDataCenter : ISingleton { #region Attr private readonly SqlSugarRepository _cbCameraRep; private readonly SqlSugarRepository _cmMarkLableRep; private readonly IDatabase _cache; private readonly CameraDataOptions _options; private readonly ICameraSdkServer _cameraSdkServer; private readonly IMarkSearcherServer _markSearcherServer; /// /// {cameraId, List(MarkLabelCalcResult)} /// private ConcurrentDictionary> SearchResultListDict { get; set; } = new(); #endregion Attr public CameraDataCenter( IDatabase cache, ICameraSdkServer cameraSdkServer, IMarkSearcherServer markSearcherServer ) { _cbCameraRep = App.GetService>(); _cmMarkLableRep = App.GetService>(); _cache = cache; _options = App.GetOptions(); _cameraSdkServer = cameraSdkServer; _markSearcherServer = markSearcherServer; InitThread(); } #region Loop private Thread RefreshCameraPtzThread { get; set; } private Thread RefreshMarkSearcherThread { get; set; } /// /// 初始化线程 /// private void InitThread() { // 初始化 CameraPtzThread RefreshCameraPtzThread = new Thread(() => { while (true) { RefreshCameraPtzInfos(); Thread.Sleep(_options.CameraPtz.LoopInterval); } }) { IsBackground = true// 设置后台线程 }; // 启动 CameraPtzThread RefreshCameraPtzThread.Start(); // 初始化 MarkSearcherThread RefreshMarkSearcherThread = new Thread(() => { while (true) { RefreshMarkSearchers(); Thread.Sleep(_options.MarkSearcher.LoopInterval); } }) { IsBackground = true// 设置后台线程 }; // 启动 MarkSearcherThread RefreshMarkSearcherThread.Start(); } /// /// 刷新所有相机 ptz /// 有待改善,应设置超时计数机制 /// https://blog.csdn.net/qq_28368039/article/details/118597396 /// private async void RefreshCameraPtzInfos() { HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraIpCounts); List tasks = new(); foreach (HashEntry entry in entries) { string cameraIp = entry.Name; tasks.Add(RefreshCameraPtzInfo(cameraIp)); } await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout)); } /// /// 刷新相机 ptz /// /// /// private async Task RefreshCameraPtzInfo(string cameraIp) { bool ret = _cameraSdkServer.GetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo); if (!ret) return; await _cache.HashSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson()); } /// /// 刷新所有 markSearcher /// private async void RefreshMarkSearchers() { HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraId2Ip); List tasks = new(); foreach (HashEntry entry in entries) { string cameraId = entry.Name; tasks.Add(RefreshMarkSearcher(cameraId.ToLong())); } await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout)); } /// /// 刷新 markSearcher /// /// /// private async Task RefreshMarkSearcher(long cameraId) { MarkSearcherBase markSearcher = _markSearcherServer.GetSearcher(cameraId); if (markSearcher == null) return; string cameraIp = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId); RedisValue value = _cache.HashGet(CacheInfo.CameraPtzInfos, cameraIp); if (value.IsNull) return; PtzInfo ptzInfo = value.ToString().FromJson(); markSearcher.UpdateCameraCalcParams(ptzInfo); List resultList = await markSearcher.SearchAsync(); SearchResultListDict[cameraId] = resultList; } #endregion Loop #region Base Method public List GetMarkLabelCalcResultList(long cameraId) { bool ret = SearchResultListDict.TryGetValue(cameraId, out List resultList); return ret ? resultList : new List(); } #endregion Base Method #region Base Method Async public async Task> GetMarkLabelCalcResultListAsync(long cameraId) { return await Task.Run(() => { return GetMarkLabelCalcResultList(cameraId); }); } #endregion Base Method Async }