75 lines
2.7 KiB
C#
75 lines
2.7 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|