Browse Source

Some change

master
fajiao 2 years ago
parent
commit
dbdad53324
  1. 609
      Cis.Application/Core/Center/CameraDataCenter.cs
  2. 1
      Cis.Application/GlobalUsings.cs
  3. 4
      Cis.Application/Startup.cs
  4. 2
      Cis.Application/Sys/Common/SysInfo.cs
  5. 14
      Cis.Web.Entry/Program.cs

609
Cis.Application/Core/Center/CameraDataCenter.cs

@ -1,312 +1,317 @@
using Cis.Application.Cb;
using Cis.Application.Cm;
using Cis.Application.Tb;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
namespace Cis.Application.Core;
public class CameraDataCenter
{
#region Attr
private readonly SqlSugarRepository<CbCamera> _cbCameraRep;
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep;
private readonly PtzServerApi _ptzServerApi;
private readonly CameraDataOptions options = App.GetOptions<CameraDataOptions>();
private Thread _thread { get; set; }
/// <summary>
/// (cbCameraId, cbCameraIp)
/// </summary>
private Dictionary<long, string> _cbCameraId2IpDict { get; set; } = new();
/// <summary>
/// (cameraIp, TbPtzCamera)
/// </summary>
private ConcurrentDictionary<string, TbPtzCamera> _tbPtzCameraDict { get; set; } = new();
/// <summary>
/// (cameraIp, PtzInfo)
/// </summary>
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new();
/// <summary>
/// _markSearcherDict 锁对象,写锁
/// </summary>
private static ReaderWriterLockSlim msDictLock { get; } = new();
/// <summary>
/// (cbCameraId, MarkSearcherBase)
/// </summary>
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new();
/// <summary>
/// (cameraId, List(MarkLabelCalcResult))
/// </summary>
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> _markLabelCalcResultListDict { get; set; } = new();
#endregion Attr
public CameraDataCenter()
{
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>();
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>();
_tbPtzCameraRep = App.GetService<SqlSugarRepository<TbPtzCamera>>();
_ptzServerApi = App.GetService<PtzServerApi>();
Init();
}
private void Init()
{
if (!options.LazyInit)
{
List<TbPtzCamera> list = _tbPtzCameraRep.GetList();
// 根据 Ip 去重
foreach (TbPtzCamera item in list)
{
if (!_tbPtzCameraDict.ContainsKey(item.Ip))
_tbPtzCameraDict[item.Ip] = item;
}
}
// 初始化 thread
_thread = new Thread(WorkLoop)
{
IsBackground = true// 设置后台线程
};
_thread.Start();
}
#region Loop
/// <summary>
/// 循环运行
/// </summary>
private void WorkLoop()
{
while (true)
{
RefreshPtzInfoByApi();
RefreshMarkSearcher();
Thread.Sleep(options.LoopInterval);
}
}
private void RefreshPtzInfoByApi()
{
foreach (TbPtzCamera item in _tbPtzCameraDict.Values)
{
PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId);
_cameraPtzInfoDict[item.Ip] = ptzInfo;
}
}
private void RefreshMarkSearcher()
{
foreach (KeyValuePair<long, MarkSearcherBase> pair in _markSearcherDict)
{
long cameraId = pair.Key;
MarkSearcherBase markSearcher = pair.Value;
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp);
if (!ret) continue;
ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo);
if (!ret) continue;
markSearcher.UpdateCameraCalcInfo(ptzInfo);
List<MarkLabelCalcResult> resultList = markSearcher.Calc();
_markLabelCalcResultListDict[cameraId] = resultList;
}
}
#endregion Loop
#region external call
/// <summary>
/// 激活 cbCamera 进入运算
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
public bool ActivateSearcher(long cameraId)
{
try
{
msDictLock.EnterWriteLock();
if (_markSearcherDict.ContainsKey(cameraId))
return false;
// 获取 cbCamera
CbCamera cbCamera = _cbCameraRep.GetById(cameraId);
if (cbCamera == null) return false;
// 获取 tbPtzCamera
string cameraIp = cbCamera.Ip;
bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera);
if (!ret)
{
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp);
if (tbPtzCamera == null) return false;
_tbPtzCameraDict[cameraIp] = tbPtzCamera;
}
// 存储 cbCamera id 对应 ip 关系
_cbCameraId2IpDict[cbCamera.Id] = cameraIp;
// 创建 cameraCalcInfo
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id));
// 创建 markSeacher
HikMarkSeacher markSeacher = new(cameraCalcInfo);
// 获取 cmMarkLabel 列表
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId);
// 将 cmMarkLabel 一一添加到 markSeacher
foreach (CmMarkLabel item in cmMarkLabelList)
{
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
item.Id,
PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition),
item.VideoWidth,
item.VideoHeight,
item.CanvasLeftRatio,
item.CanvasTopRatio
);
markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo);
}
// 将 markSeacher 放入字典
_markSearcherDict[cameraId] = markSeacher;
}
finally
{
msDictLock.ExitWriteLock();
}
return true;
}
/// <summary>
/// 解除 cbCamera 进入运算
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
public bool DeActivateSearcher(long cameraId)
{
try
{
msDictLock.EnterWriteLock();
_markSearcherDict.Remove(cameraId);
_markLabelCalcResultListDict.Remove(cameraId);
}
finally
{
msDictLock.ExitWriteLock();
}
return true;
}
public bool IsExistSearcher(long cameraId)
{
return _markSearcherDict.ContainsKey(cameraId);
}
public bool ActivateMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher);
if (!ret)
return false;
if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId))
return false;
CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId);
if (label == null)
return false;
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
label.Id,
PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition),
label.VideoWidth,
label.VideoHeight,
label.CanvasLeftRatio,
label.CanvasTopRatio
);
return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo);
}
public bool DectivateMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher);
return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false;
}
public bool IsExistCameraMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) &&
markSearcher.ExistsMarkLabelCalcInfo(markLabelId);
return ret;
}
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId)
{
bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> list);
return ret ? list : new();
}
public PtzInfo GetCameraPtzInfo(long cameraId)
{
PtzInfo ptzInfo = null;
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId,out string cameraIp) &&
_cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo);
return ret ? ptzInfo : null;
}
public async Task<bool> ActivateSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return ActivateSearcher(cameraId);
});
}
public async Task<bool> DeActivateSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return DeActivateSearcher(cameraId);
});
}
public async Task<bool> IsExistSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return IsExistSearcher(cameraId);
});
}
public async Task<bool> ActivateMarkLabelAsync(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return ActivateMarkLabel(cameraId, markLabelId);
});
}
public async Task<bool> DeactivateMarkLabelAsync(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return DectivateMarkLabel(cameraId, markLabelId);
});
}
public async Task<bool> IsExistMarkLabelAysnc(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return IsExistCameraMarkLabel(cameraId, markLabelId);
});
}
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId)
{
return await Task.Run(() =>
{
return GetMarkLabelCalcResultList(cameraId);
});
}
#endregion external call
#region Attr
private readonly SqlSugarRepository<CbCamera> _cbCameraRep;
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep;
private readonly PtzServerApi _ptzServerApi;
private readonly CameraDataOptions options;
private Thread _thread { get; set; }
/// <summary>
/// (cbCameraId, cbCameraIp)
/// </summary>
private Dictionary<long, string> _cbCameraId2IpDict { get; set; } = new();
/// <summary>
/// (cameraIp, TbPtzCamera)
/// </summary>
private ConcurrentDictionary<string, TbPtzCamera> _tbPtzCameraDict { get; set; } = new();
/// <summary>
/// (cameraIp, PtzInfo)
/// </summary>
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new();
/// <summary>
/// _markSearcherDict 锁对象,写锁
/// </summary>
private static ReaderWriterLockSlim msDictLock { get; } = new();
/// <summary>
/// (cbCameraId, MarkSearcherBase)
/// </summary>
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new();
/// <summary>
/// (cameraId, List(MarkLabelCalcResult))
/// </summary>
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> _markLabelCalcResultListDict { get; set; } = new();
#endregion Attr
private readonly ILogger<CameraDataCenter> _logger;
public CameraDataCenter()
{
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>();
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>();
_tbPtzCameraRep = App.GetService<SqlSugarRepository<TbPtzCamera>>();
_ptzServerApi = App.GetService<PtzServerApi>();
options = App.GetOptions<CameraDataOptions>();
_logger = App.GetService<ILogger<CameraDataCenter>>();
Init();
}
private void Init()
{
if (!options.LazyInit)
{
List<TbPtzCamera> list = _tbPtzCameraRep.GetList();
// 根据 Ip 去重
foreach (TbPtzCamera item in list)
{
if (!_tbPtzCameraDict.ContainsKey(item.Ip))
_tbPtzCameraDict[item.Ip] = item;
}
}
// 初始化 thread
_thread = new Thread(WorkLoop)
{
IsBackground = true// 设置后台线程
};
_thread.Start();
}
#region Loop
/// <summary>
/// 循环运行
/// </summary>
private void WorkLoop()
{
while (true)
{
RefreshPtzInfoByApi();
RefreshMarkSearcher();
Thread.Sleep(options.LoopInterval);
}
}
private void RefreshPtzInfoByApi()
{
foreach (TbPtzCamera item in _tbPtzCameraDict.Values)
{
PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId);
_cameraPtzInfoDict[item.Ip] = ptzInfo;
}
}
private async void RefreshMarkSearcher()
{
foreach (KeyValuePair<long, MarkSearcherBase> pair in _markSearcherDict)
{
long cameraId = pair.Key;
MarkSearcherBase markSearcher = pair.Value;
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp);
if (!ret) continue;
ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo);
if (!ret) continue;
markSearcher.UpdateCameraCalcInfo(ptzInfo);
List<MarkLabelCalcResult> resultList = await markSearcher.CalcAsync();
_markLabelCalcResultListDict[cameraId] = resultList;
}
}
#endregion Loop
#region external call
/// <summary>
/// 激活 cbCamera 进入运算
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
public bool ActivateSearcher(long cameraId)
{
try
{
msDictLock.EnterWriteLock();
if (_markSearcherDict.ContainsKey(cameraId))
return false;
// 获取 cbCamera
CbCamera cbCamera = _cbCameraRep.GetById(cameraId);
if (cbCamera == null) return false;
// 获取 tbPtzCamera
string cameraIp = cbCamera.Ip;
bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera);
if (!ret)
{
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp);
if (tbPtzCamera == null) return false;
_tbPtzCameraDict[cameraIp] = tbPtzCamera;
}
// 存储 cbCamera id 对应 ip 关系
_cbCameraId2IpDict[cbCamera.Id] = cameraIp;
// 创建 cameraCalcInfo
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id));
// 创建 markSeacher
HikMarkSeacher markSeacher = new(cameraCalcInfo);
// 获取 cmMarkLabel 列表
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId);
// 将 cmMarkLabel 一一添加到 markSeacher
foreach (CmMarkLabel item in cmMarkLabelList)
{
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
item.Id,
PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition),
item.VideoWidth,
item.VideoHeight,
item.CanvasLeftRatio,
item.CanvasTopRatio
);
markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo);
}
// 将 markSeacher 放入字典
_markSearcherDict[cameraId] = markSeacher;
}
finally
{
msDictLock.ExitWriteLock();
}
return true;
}
/// <summary>
/// 解除 cbCamera 进入运算
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
public bool DeActivateSearcher(long cameraId)
{
try
{
msDictLock.EnterWriteLock();
_markSearcherDict.Remove(cameraId);
_markLabelCalcResultListDict.Remove(cameraId);
}
finally
{
msDictLock.ExitWriteLock();
}
return true;
}
public bool IsExistSearcher(long cameraId)
{
return _markSearcherDict.ContainsKey(cameraId);
}
public bool ActivateMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher);
if (!ret)
return false;
if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId))
return false;
CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId);
if (label == null)
return false;
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
label.Id,
PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition),
label.VideoWidth,
label.VideoHeight,
label.CanvasLeftRatio,
label.CanvasTopRatio
);
return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo);
}
public bool DectivateMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher);
return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false;
}
public bool IsExistCameraMarkLabel(long cameraId, long markLabelId)
{
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) &&
markSearcher.ExistsMarkLabelCalcInfo(markLabelId);
return ret;
}
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId)
{
bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> list);
return ret ? list : new();
}
public PtzInfo GetCameraPtzInfo(long cameraId)
{
PtzInfo ptzInfo = null;
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp) &&
_cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo);
return ret ? ptzInfo : null;
}
public async Task<bool> ActivateSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return ActivateSearcher(cameraId);
});
}
public async Task<bool> DeActivateSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return DeActivateSearcher(cameraId);
});
}
public async Task<bool> IsExistSearcherAsync(long cameraId)
{
return await Task.Run(() =>
{
return IsExistSearcher(cameraId);
});
}
public async Task<bool> ActivateMarkLabelAsync(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return ActivateMarkLabel(cameraId, markLabelId);
});
}
public async Task<bool> DeactivateMarkLabelAsync(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return DectivateMarkLabel(cameraId, markLabelId);
});
}
public async Task<bool> IsExistMarkLabelAysnc(long cameraId, long markLabelId)
{
return await Task.Run(() =>
{
return IsExistCameraMarkLabel(cameraId, markLabelId);
});
}
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId)
{
return await Task.Run(() =>
{
return GetMarkLabelCalcResultList(cameraId);
});
}
#endregion external call
}

1
Cis.Application/GlobalUsings.cs

@ -3,6 +3,7 @@ global using Furion;
global using Furion.ConfigurableOptions;
global using Furion.DependencyInjection;
global using Furion.DynamicApiController;
global using Furion.FriendlyException;
global using Microsoft.AspNetCore.Mvc;
global using SqlSugar;
global using System.ComponentModel.DataAnnotations;

4
Cis.Application/Startup.cs

@ -17,8 +17,8 @@ public class Startup : AppStartup
services.AddConfigurableOptions<CameraDataOptions>();
services.AddConfigurableOptions<PtzServerOptions>();
services.AddSingleton<CameraDataCenter>(new CameraDataCenter());
}
services.AddSingleton(new CameraDataCenter());
}
/// <summary>
/// 配置应用请求处理管道

2
Cis.Application/Sys/Common/SysInfo.cs

@ -10,7 +10,7 @@ public class SysInfo
/// <summary>
/// Api 分组名
/// </summary>
public const string GroupName = "Sys";
public const string GroupName = "System";
/// <summary>
/// Api 分组排序

14
Cis.Web.Entry/Program.cs

@ -1 +1,13 @@
Serve.Run(RunOptions.Default.WithArgs(args));
Serve.Run(RunOptions.Default.AddWebComponent<WebComponent>().WithArgs(args));
public class WebComponent : IWebComponent
{
public void Load(WebApplicationBuilder builder, ComponentContext componentContext)
{
// ÈÕÖ¾¹ýÂË
builder.Logging.AddFilter((provider, category, logLevel) =>
{
return !new[] { "Microsoft.Hosting", "Microsoft.AspNetCore" }.Any(u => category.StartsWith(u)) && logLevel >= LogLevel.Information;
});
}
}
Loading…
Cancel
Save