完善契约与客户端、服务端的收发代码

This commit is contained in:
2026-01-03 00:16:28 +08:00
parent d039559402
commit dcf424a86e
30 changed files with 3292 additions and 349 deletions

View File

@@ -0,0 +1,123 @@
using Newtonsoft.Json;
using SHH.CameraSdk;
using SHH.Contracts;
namespace SHH.CameraService
{
/// <summary>
/// 指令业务逻辑分发器 (纯逻辑层)
/// <para>职责:解析业务参数 -> 调用 CameraManager -> 返回执行结果</para>
/// <para>注意:本类不处理网络协议,也不负责 RequestId 的回填,只关注业务本身</para>
/// </summary>
public static class CommandBusProcessor
{
/// <summary>
/// 核心业务入口
/// </summary>
/// <param name="manager">相机管理器实例</param>
/// <param name="payload">已解析的指令包</param>
/// <returns>执行结果 (不含 RequestId由调用方补充)</returns>
public static CommandResult ProcessBusinessLogic(CameraManager manager, CommandPayload payload)
{
string cmd = payload.CmdCode.ToUpper();
// 忽略客户端发回的 ACK (如果是双向确认模式)
if (cmd == "REGISTER_ACK") return CommandResult.Ok();
// 解析 TargetId (CameraId)
long deviceId = 0;
// 只有非 SYSTEM 指令才需要解析设备ID
if (payload.TargetId != "SYSTEM" && !long.TryParse(payload.TargetId, out deviceId))
{
return CommandResult.Fail($"Invalid Device ID: {payload.TargetId}");
}
try
{
switch (cmd)
{
// ==========================================
// 1. PTZ 云台控制
// ==========================================
case "PTZ":
{
var device = manager.GetDevice(deviceId);
if (device == null) return CommandResult.Fail("Device Not Found");
if (!device.IsOnline) return CommandResult.Fail("Device Offline");
// 检查设备是否支持 PTZ 能力 (接口模式匹配)
if (device is IPtzFeature ptzFeature)
{
var ptzDto = JsonConvert.DeserializeObject<PtzControlDto>(payload.JsonParams);
if (ptzDto == null) return CommandResult.Fail("Invalid PTZ Params");
// 异步转同步执行 (Task.Wait 在后台线程是安全的)
if (ptzDto.Duration > 0)
{
// 点动模式 (例如:向左转 500ms)
ptzFeature.PtzStepAsync(ptzDto.Action, ptzDto.Duration, ptzDto.Speed).Wait();
}
else
{
// 持续模式 (开始转/停止转)
ptzFeature.PtzControlAsync(ptzDto.Action, ptzDto.Stop, ptzDto.Speed).Wait();
}
return CommandResult.Ok("PTZ Executed");
}
return CommandResult.Fail("Device does not support PTZ");
}
// ==========================================
// 2. 远程重启
// ==========================================
case "REBOOT":
{
var device = manager.GetDevice(deviceId);
if (device == null) return CommandResult.Fail("Device Not Found");
if (device is IRebootFeature rebootFeature)
{
rebootFeature.RebootAsync().Wait();
return CommandResult.Ok("Reboot command sent");
}
return CommandResult.Fail("Device does not support Reboot");
}
// ==========================================
// 3. 时间同步
// ==========================================
case "SYNC_TIME":
{
var device = manager.GetDevice(deviceId);
if (device == null) return CommandResult.Fail("Device Not Found");
if (device is ITimeSyncFeature timeFeature)
{
timeFeature.SetTimeAsync(DateTime.Now).Wait();
return CommandResult.Ok("Time synced");
}
return CommandResult.Fail("Device does not support TimeSync");
}
// ==========================================
// 4. 系统级指令 (心跳/诊断)
// ==========================================
case "PING":
return CommandResult.Ok("PONG");
default:
return CommandResult.Fail($"Unknown Command: {cmd}");
}
}
catch (AggregateException ae)
{
// 捕获异步任务内部的异常
return CommandResult.Fail($"Execution Error: {ae.InnerException?.Message}");
}
catch (Exception ex)
{
return CommandResult.Fail($"Execution Error: {ex.Message}");
}
}
}
}