Files
Ayay/SHH.CameraService/Core/CmdClients/CommandDispatcher.cs
wilson 3351ae739e 在 AiVideo 中能看到图像
增加了在线状态同步逻辑
2026-01-09 12:30:36 +08:00

91 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 文件: Core\CmdClients\CommandDispatcher.cs
using MessagePack;
using Newtonsoft.Json.Linq;
using SHH.Contracts;
using System.Text;
namespace SHH.CameraService;
public class CommandDispatcher
{
// 1. 注入路由表
private readonly Dictionary<string, ICommandHandler> _handlers;
// 2. 定义回执事件 (ACK闭环的核心)
public event Action<CommandResult>? OnResponseReady;
// 3. 构造函数:注入所有 Handler
public CommandDispatcher(IEnumerable<ICommandHandler> handlers)
{
// 将注入的 Handler 转换为字典Key = ActionName (e.g. "SyncCamera")
_handlers = handlers.ToDictionary(h => h.ActionName, h => h, StringComparer.OrdinalIgnoreCase);
}
public async Task DispatchAsync(string protocol, byte[] data)
{
try
{
// 只处理 COMMAND 协议
if (protocol != ProtocolHeaders.Command) return;
// 反序列化信封
var envelope = MessagePackSerializer.Deserialize<CommandPayload>(data);
if (envelope == null) return;
string cmdCode = envelope.CmdCode; // e.g. "SyncCamera"
Console.WriteLine($"[分发] 收到指令: {cmdCode} (ID: {envelope.RequestId})");
bool isSuccess = true;
string message = "OK";
// --- 路由匹配逻辑 ---
if (_handlers.TryGetValue(cmdCode, out var handler))
{
try
{
// 数据适配:你的 Handler 需要 JToken
// 如果 envelope.JsonParams 是空的,传个空对象防止报错
var jsonStr = string.IsNullOrEmpty(envelope.JsonParams) ? "{}" : envelope.JsonParams;
var token = JToken.Parse(jsonStr);
// ★★★ 核心:调用 SyncCameraHandler.ExecuteAsync ★★★
await handler.ExecuteAsync(token);
message = $"Executed {cmdCode}";
}
catch (Exception ex)
{
isSuccess = false;
message = $"Handler Error: {ex.Message}";
Console.WriteLine($"[业务异常] {message}");
}
}
else
{
isSuccess = false;
message = $"No handler found for {cmdCode}";
Console.WriteLine($"[警告] {message}");
}
// --- ACK 闭环逻辑 ---
if (envelope.RequireAck)
{
var result = new CommandResult
{
Protocol = ProtocolHeaders.CommandResult,
RequestId = envelope.RequestId, // 必须带回 ID
Success = isSuccess,
Message = message,
Timestamp = DateTime.Now.Ticks
};
// 触发事件
OnResponseReady?.Invoke(result);
}
}
catch (Exception ex)
{
Console.WriteLine($"[Dispatcher] 致命错误: {ex.Message}");
}
}
}