106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
using System.Collections.Concurrent;
|
||
using System.Diagnostics;
|
||
|
||
namespace SHH.MjpegPlayer
|
||
{
|
||
/// <summary>
|
||
/// 设备配置同步处理器 (原 ConfigSyncManager 瘦身版)
|
||
/// 职责:仅负责确保远程分析节点(Instance)的摄像头配置与本地数据库一致。
|
||
/// 逻辑:通过 5 秒初始化冷却期避开抖动,并利用配置快照对比实现增量同步。
|
||
/// </summary>
|
||
public class DeviceConfigHandler
|
||
{
|
||
#region 单例与核心存储字段
|
||
|
||
/// <summary>
|
||
/// 获取配置处理器的全局单例实例
|
||
/// </summary>
|
||
public static DeviceConfigHandler Instance { get; } = new DeviceConfigHandler();
|
||
|
||
/// <summary>
|
||
/// 活跃服务实例 ID 集合 (InstanceId)
|
||
/// 用于记录当前所有已建立 gRpc 长连接的远程节点
|
||
/// </summary>
|
||
private readonly ConcurrentHashSet<string> _activeServiceIds = new ConcurrentHashSet<string>();
|
||
|
||
/// <summary>
|
||
/// 配置快照缓存:用于防止重复下发相同的配置
|
||
/// Key 格式: "InstanceId_CameraId"
|
||
/// Value: 该摄像头配置的 JSON 字符串快照
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, string> _lastSentConfigCache = new ConcurrentDictionary<string, string>();
|
||
|
||
/// <summary>
|
||
/// 后台监控任务的任务取消令牌源
|
||
/// </summary>
|
||
private CancellationTokenSource _cts;
|
||
|
||
/// <summary>
|
||
/// 初始化完成时间戳:用于 5 秒冷却期判定
|
||
/// 防止在服务刚启动或节点刚连接时,由于数据库加载延迟导致误判设备被移除
|
||
/// </summary>
|
||
private DateTime _initCompleteTime = DateTime.MaxValue;
|
||
|
||
#endregion
|
||
|
||
#region 构造函数与初始化
|
||
|
||
/// <summary>
|
||
/// 私有构造函数:订阅消息总线并启动监控任务
|
||
/// </summary>
|
||
private DeviceConfigHandler()
|
||
{
|
||
// 订阅总线:仅关注节点注册事件,以此作为触发初始化全量同步的开关
|
||
MessageBus.Instance.OnServerRegistered += async (payload) =>
|
||
{
|
||
await HandleServiceOnlineAsync(payload.InstanceId);
|
||
};
|
||
|
||
// 启动后台轮询监控任务 (检测 Add/Update/Remove)
|
||
StartMonitorTask();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 核心业务处理 (节点上线)
|
||
|
||
/// <summary>
|
||
/// 处理新节点上线:执行全量同步
|
||
/// </summary>
|
||
/// <param name="instanceId">远程服务实例唯一标识</param>
|
||
private async Task HandleServiceOnlineAsync(string instanceId)
|
||
{
|
||
// 1. 将新实例记录到活跃列表
|
||
_activeServiceIds.Add(instanceId);
|
||
|
||
// 2. 预留 1 秒等待期,确保 gRpc 双向通道完全稳定
|
||
await Task.Delay(1000);
|
||
|
||
//// 3. 从数据库拍摄当前所有摄像头的快照
|
||
//var snapshot = CSdkStatics.DbCameras.ToList();
|
||
|
||
//// 4. 对新节点执行全量下发
|
||
//foreach (var cam in snapshot)
|
||
//{
|
||
// await SendSyncCommandAsync(instanceId, cam);
|
||
//}
|
||
|
||
// 5. 更新冷却期起始点
|
||
_initCompleteTime = DateTime.Now;
|
||
Debug.WriteLine($"[ConfigHandler] 节点 {instanceId} 初始化全量同步已完成。");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 后台监控任务 (增量同步)
|
||
|
||
/// <summary>
|
||
/// 启动后台增量监控任务
|
||
/// </summary>
|
||
private void StartMonitorTask()
|
||
{
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |