Files
Ayay/SHH.NetMQ/DistributorServer.cs

71 lines
2.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using NetMQ;
using NetMQ.Sockets;
using SHH.Contracts;
namespace SHH.NetMQ
{
/// <summary>
/// 视频分发服务端 (Publisher)
/// 特性:非阻塞、防内存溢出
/// </summary>
public class DistributorServer : IDisposable
{
private PublisherSocket _pubSocket;
private readonly object _lock = new object();
// 配置:高水位限制 (HWM)
// 假设 25fps设置 50 意味着内存只缓存 2 秒的视频。
// 如果断网超过 2 秒,新来的视频帧直接丢弃,优先保证恢复后的实时性。
private const int HWM_LIMIT = 50;
public DistributorServer(string connectionString)
{
_pubSocket = new PublisherSocket();
// 1. 设置发送缓冲区大小 (防爆内存关键)
_pubSocket.Options.SendHighWatermark = HWM_LIMIT;
// 2. 绑定地址 (如 tcp://*:5555)
_pubSocket.Bind(connectionString);
}
public void Broadcast(VideoPayload payload)
{
if (payload == null) return;
// 补充发送时间
payload.DispatchTime = DateTime.Now;
// 准备数据帧
string jsonMeta = payload.GetMetadataJson();
byte[] rawBytes = payload.OriginalImageBytes ?? new byte[0];
byte[] targetBytes = payload.TargetImageBytes ?? new byte[0];
// 使用 NetMQMessage 封装多帧消息
// 这样比手动调三次 Send 更容易管理原子性
var msg = new NetMQMessage();
msg.Append(jsonMeta); // 第1帧
msg.Append(rawBytes); // 第2帧
msg.Append(targetBytes); // 第3帧
lock (_lock)
{
// 3. 非阻塞发送 (核心防卡死代码)
// TimeSpan.Zero 表示:如果缓冲区满了或者发不出去,立即放弃,不等待,返回 false
// 这样你的主线程海康SDK回调永远不会被卡住
bool sent = _pubSocket.TrySendMultipartMessage(TimeSpan.Zero, msg);
if (!sent)
{
// 这里可以打个日志Console.WriteLine("警告:网络拥堵,丢帧中...");
}
}
}
public void Dispose()
{
_pubSocket?.Dispose();
}
}
}