using Cis.Application.Core.Component.MarkSeacher; using Cis.Application.Core.Component.PtzServer; using EC.Helper.CameraSDK; using FreeRedis; using StackExchange.Profiling.Internal; using System.Collections.Concurrent; namespace Cis.Application.Core; public class CameraDataCenter : ISingleton { #region Attr private readonly RedisClient _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( RedisClient cache, ICameraSdkServer cameraSdkServer, IMarkSearcherServer markSearcherServer ) { _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(async () => { while (true) { await RefreshCameraPtzInfos(); Thread.Sleep(_options.CameraPtz.LoopInterval); } }) { IsBackground = true// 设置后台线程 }; // 启动 CameraPtzThread RefreshCameraPtzThread.Start(); //// 初始化 MarkSearcherThread //RefreshMarkSearcherThread = new Thread(async () => //{ // while (true) // { // await RefreshMarkSearchers(); // Thread.Sleep(_options.MarkSearcher.LoopInterval); // } //}) //{ // IsBackground = true// 设置后台线程 //}; //// 启动 MarkSearcherThread //RefreshMarkSearcherThread.Start(); } /// /// 刷新所有相机 ptz /// 有待改善,应设置超时计数机制 /// https://blog.csdn.net/qq_28368039/article/details/118597396 /// private async Task RefreshCameraPtzInfos() { string[] cameraIpList = await _cache.HKeysAsync(CacheInfo.CameraIpCounts); List tasks = new(); foreach (string cameraIp in cameraIpList) { 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.TryGetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo); if (!ret) return; await _cache.HSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson()); } /// /// 刷新所有 markSearcher /// private async Task RefreshMarkSearchers() { string[] cameraIdList = await _cache.HKeysAsync(CacheInfo.CameraId2Ip); List tasks = new(); foreach (string cameraId in cameraIdList) { 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 = await _cache.HGetAsync(CacheInfo.CameraId2Ip, cameraId.ToString()); string ptzInfoStr = await _cache.HGetAsync(CacheInfo.CameraPtzInfos, cameraIp); if (string.IsNullOrEmpty(ptzInfoStr)) return; PtzInfo ptzInfo = ptzInfoStr.ToObject(); if (ptzInfo == null) return; 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 }