76 lines
2.8 KiB
C#
76 lines
2.8 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,
|
||
};
|
||
payload.SubscriberIds.AddRange(frame.SubscriberIds);
|
||
|
||
// 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);
|
||
}
|
||
}
|
||
} |