添加契约和网络传输类库

This commit is contained in:
2025-12-29 08:09:14 +08:00
parent 231247c80f
commit 8cd36f44ac
14 changed files with 748 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
using Microsoft.Extensions.Hosting;
using OpenCvSharp;
using SHH.Contracts;
using SHH.NetMQ;
namespace SHH.CameraSdk
{
public class ZeroMqBridgeService : BackgroundService
{
private readonly DistributorServer _distributor;
private readonly ForwarderClient _forwarder;
public ZeroMqBridgeService(DistributorServer distributor, ForwarderClient forwarder)
{
_distributor = distributor;
_forwarder = forwarder;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
Console.WriteLine("[Bridge] 正在连接全局广播总线...");
// 【关键修改】直接订阅静态的全局事件
// 不需要传入 APP_ID因为这是 C# 原生事件,不是字典查找
GlobalStreamDispatcher.OnGlobalFrame += BridgeHandler;
Console.WriteLine("[Bridge] 全局总线连接成功!任何动态增删的设备都会自动转发。");
return Task.CompletedTask;
}
// 真正的事件处理函数
private void BridgeHandler(long deviceId, SmartFrame frame)
{
try
{
// 1. 安全检查
var sourceMat = frame.TargetMat ?? frame.InternalMat;
if (sourceMat == null || sourceMat.Empty()) return;
// 2. 内存克隆 (Deep Copy) - 这一步不能省
using var safeMat = sourceMat.Clone();
// 3. 编码 & 封装
// 建议:可以在这里判断一下 deviceId如果某些设备不想发可以在这里 return
var jpgParams = new int[] { (int)ImwriteFlags.JpegQuality, 70 };
byte[] jpgBytes = safeMat.ImEncode(".jpg", jpgParams);
var payload = new VideoPayload
{
CameraId = deviceId.ToString(),
CaptureTime = DateTime.Now,
DispatchTime = DateTime.Now,
OriginalWidth = safeMat.Width,
OriginalHeight = safeMat.Height,
OriginalImageBytes = jpgBytes
};
// 4. 发射
_distributor.Broadcast(payload);
_forwarder.Push(payload);
}
catch (Exception ex)
{
// Console.WriteLine(ex.Message); // 生产环境建议注释掉,防止日志刷屏
}
}
public override Task StopAsync(CancellationToken cancellationToken)
{
// 优雅退订,防止内存泄漏
GlobalStreamDispatcher.OnGlobalFrame -= BridgeHandler;
return base.StopAsync(cancellationToken);
}
}
}