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;
await markSearcher.UpdateCameraCalcParamsAsync(ptzInfo);
}
#endregion Loop
}