在 AiVideo 中能看到图像
增加了在线状态同步逻辑
This commit is contained in:
@@ -1,46 +1,91 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
// 文件: Core\CmdClients\CommandDispatcher.cs
|
||||
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SHH.Contracts;
|
||||
using System.Text;
|
||||
|
||||
namespace SHH.CameraService;
|
||||
|
||||
public class CommandDispatcher
|
||||
{
|
||||
// 路由表:Key = ActionName, Value = Handler
|
||||
// 1. 注入路由表
|
||||
private readonly Dictionary<string, ICommandHandler> _handlers;
|
||||
|
||||
// 通过依赖注入拿到所有实现了 ICommandHandler 的类
|
||||
// 2. 定义回执事件 (ACK闭环的核心)
|
||||
public event Action<CommandResult>? OnResponseReady;
|
||||
|
||||
// 3. 构造函数:注入所有 Handler
|
||||
public CommandDispatcher(IEnumerable<ICommandHandler> handlers)
|
||||
{
|
||||
_handlers = handlers.ToDictionary(h => h.ActionName, h => h);
|
||||
// 将注入的 Handler 转换为字典,Key = ActionName (e.g. "SyncCamera")
|
||||
_handlers = handlers.ToDictionary(h => h.ActionName, h => h, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public async Task DispatchAsync(string jsonMessage)
|
||||
public async Task DispatchAsync(string protocol, byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jObj = JObject.Parse(jsonMessage);
|
||||
string action = jObj["Action"]?.ToString();
|
||||
var payload = jObj["Payload"];
|
||||
// 只处理 COMMAND 协议
|
||||
if (protocol != ProtocolHeaders.Command) return;
|
||||
|
||||
if (string.IsNullOrEmpty(action)) return;
|
||||
// 反序列化信封
|
||||
var envelope = MessagePackSerializer.Deserialize<CommandPayload>(data);
|
||||
if (envelope == null) return;
|
||||
|
||||
// 1. 查找是否有对应的处理器
|
||||
if (_handlers.TryGetValue(action, out var handler))
|
||||
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))
|
||||
{
|
||||
await handler.ExecuteAsync(payload);
|
||||
}
|
||||
else if (action == "ACK")
|
||||
{
|
||||
// ACK 是特殊的,可以直接在这里处理或者忽略
|
||||
Console.WriteLine($"[指令] 握手成功: {jObj["Message"]}");
|
||||
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
|
||||
{
|
||||
Console.WriteLine($"[警告] 未知的指令: {action}");
|
||||
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($"[分发错误] {ex.Message}");
|
||||
Console.WriteLine($"[Dispatcher] 致命错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user