using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace SHH.CameraDashboard { public partial class CameraRepository { // 文件: Services\WebApis\CameraReps\CameraRepository.cs public async Task UpdateSubscriptionAsync(long cameraId, SubscriptionDto dto) { var serviceNode = AppGlobal.UseServiceNode; if (serviceNode == null) return false; // URL: POST /api/Cameras/{id}/subscriptions string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions"; try { string jsonBody = JsonHelper.Serialize(dto); // 发送 POST 请求 await WebApiService.Instance.PostAsync(requestUrl, jsonBody, "更新订阅配置"); return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"更新订阅失败: {ex.Message}"); return false; } } /// /// [新增] 获取订阅列表 /// public async Task> GetSubscriptionsAsync(long cameraId) { var serviceNode = AppGlobal.UseServiceNode; if (serviceNode == null) return new List(); // URL: GET /api/Cameras/{id}/subscriptions string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions"; try { string json = await WebApiService.Instance.GetAsync(requestUrl, "获取订阅列表"); // 如果返回空或null,返回空列表 if (string.IsNullOrEmpty(json)) return new List(); var list = JsonHelper.Deserialize>(json); return list ?? new List(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"获取订阅列表失败: {ex.Message}"); return new List(); } } /// /// [修改] 删除/注销订阅 /// 改为标准的 DELETE 请求 /// public async Task DeleteSubscriptionAsync(long cameraId, string appId) { if (string.IsNullOrWhiteSpace(appId)) return false; var serviceNode = AppGlobal.UseServiceNode; if (serviceNode == null) return false; // 拼接 URL: DELETE /api/Cameras/1001/subscriptions/Client_01 // 注意:AppId 如果包含特殊字符,建议 UrlEncode,但一般 ID 都是字母数字 string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions/{appId}"; try { // 调用刚刚在 WebApiService 里加的 DeleteAsync await WebApiService.Instance.DeleteAsync(requestUrl, "注销订阅"); return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"注销订阅失败: {ex.Message}"); return false; } } } /// /// 视频流订阅配置请求对象 /// 用于定义第三方应用或内部模块对指定相机流的消费需求 /// public class SubscriptionDto { /// /// 进程唯一标识 (如 "AI_Process_01"、"Main_Display_02") /// public string AppId { get; set; } = string.Empty; /// /// 订阅业务类型。 /// 决定了后端流控引擎后续的资源分配(如是否开启录像机或渲染器)。 /// public int Type { get; set; } /// /// 显示帧率需求 (单位: fps) /// 不需要显示则设为 0,控制器会自动注销该类型需求 /// public int DisplayFps { get => TargetFps; set => TargetFps = value; } public int TargetFps { get; set; } /// /// [新增] 实际显示/分发帧率 /// JSON: "realFps" /// [JsonPropertyName("realFps")] public double RealFps { get; set; } /// /// 备注信息。 /// 用于记录订阅的用途、申请人或关联业务系统。 /// public string Memo { get; set; } = string.Empty; /// /// 窗口句柄(HWND)。 /// 仅在 Type 为 HandleDisplay 时必填。格式通常为十六进制或十进制字符串。 /// public string Handle { get; set; } = string.Empty; /// /// 录像持续时长(分钟,范围 1-60)。 /// 仅在 Type 为 LocalRecord 时有效。 /// public int RecordDuration { get; set; } /// /// 录像文件存放绝对路径。 /// 仅在 Type 为 LocalRecord 时有效,例如:C:\Recordings\Room01。 /// public string SavePath { get; set; } = string.Empty; /// /// 通讯方式协议。 /// 仅在 Type 为 NetworkTrans 或 WebPush 时有效,默认为 Network。 /// public int Protocol { get; set; } /// /// 目标接收端 IP 地址。 /// 仅在 Type 为 NetworkTrans 或 WebPush 且 Protocol 为 Network 时必填。 /// public string TargetIp { get; set; } = string.Empty; /// /// 目标接收端端口号。 /// 仅在 Type 为 NetworkTrans 或 WebPush 时必填。 /// public int TargetPort { get; set; } } /// /// 订阅业务类型枚举 /// 描述视频流的最终去向和业务用途,用于帧分发策略的路由决策 /// public enum SubscriptionType { /// /// 本地窗口渲染 /// 直接在服务器端显示器绘制(如 OpenCV Window、WinForm 控件) /// [Description("本地窗口显示")] LocalWindow = 0, /// /// 本地录像存储 /// 写入磁盘文件(如 MP4/AVI 格式,支持定时切割、循环覆盖) /// [Description("本地录像存储")] LocalRecord = 1, /// /// 句柄绑定显示 /// 渲染到指定 HWND 窗口句柄(如 SDK 硬件解码渲染到客户端控件) /// [Description("句柄绑定显示")] HandleDisplay = 2, /// /// 自定义网络传输 /// 通过私有协议转发给第三方系统(如工控机、告警服务器) /// [Description("自定义网络传输")] NetworkTrans = 3, /// /// 网页端推流 /// 转码为 Web 标准协议(如 WebRTC、HLS、RTMP)供浏览器播放 /// [Description("网页端推流")] WebPush = 4 } /// /// 网络传输协议类型 /// public enum TransportProtocol { /// 可靠传输 (默认) Tcp = 0, /// 快速传输 (可能丢包/花屏) Udp = 1, /// 组播 (节省带宽) Multicast = 2, /// 内存交互 Memory = 99, } }