using System.Text;
using Fake.RabbitMQ;
using InterfaceForward.Domain.Shared.Helpers;
using RabbitMQ.Client;
using TrackCenter.Application.Dtos.TrackPush;
using TrackCenter.Application.Events;
namespace TrackCenter.Application.Services.Broadcasting;
///
/// 对外 Topic 广播(下游仍按 Newtonsoft PascalCase 契约消费,不经 Messaging 信封)。
///
public class BroadcastingService(IRabbitMqChannelPool channelPool) : ITransientDependency
{
public void TrackChangePublicTopic(TrackChangeEto eto, string AppCode)
{
PublishByConfirmSelect(
GlobalConst.TrackChangeExchange,
ExchangeType.Topic,
$"TrackChange.{AppCode}",
Encoding.UTF8.GetBytes(eto.ToJson()),
prop => { prop.Persistent = true; });
}
///
/// 轨迹推送完成广播(批量)
///
public void TrackPushCompletedPublicTopic(List list)
{
var data = list
.Select(TrackPushRecordDtoToEvent)
.Select(x => Encoding.UTF8.GetBytes(x.ToJson()));
var log = list.First();
PublishByConfirmSelect(
GlobalConst.TrackPushExchange,
ExchangeType.Topic,
$"TrackPush.{log.AppKey}",
data,
prop => { prop.Persistent = true; });
}
///
/// 轨迹推送完成广播
///
public void TrackPushCompletedPublicTopic(TrackPushRecordDto log)
{
var data = TrackPushRecordDtoToEvent(log);
PublishByConfirmSelect(
GlobalConst.TrackPushExchange,
ExchangeType.Topic,
$"TrackPush.{log.AppKey}",
Encoding.UTF8.GetBytes(data.ToJson()),
prop => { prop.Persistent = true; });
}
///
/// 轨迹推送失败广播
///
public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
{
//暂时使用推送完成模型,后续可能会出现有区分度的模型
TrackPushCompletedPublicTopic(log);
}
private void PublishByConfirmSelect(
string exchange,
string exchangeType,
string routingKey,
byte[] data,
Action? options = null)
{
using var channelAccessor = channelPool.Acquire(routingKey);
var channel = channelAccessor.Channel;
channel.ExchangeDeclare(exchange, exchangeType, durable: true);
var props = channel.CreateBasicProperties();
options?.Invoke(props);
channel.ConfirmSelect();
channel.BasicPublish(exchange, routingKey, props, data);
channel.WaitForConfirmsOrDie();
}
private void PublishByConfirmSelect(
string exchange,
string exchangeType,
string routingKey,
IEnumerable datas,
Action? options = null)
{
using var channelAccessor = channelPool.Acquire(routingKey);
var channel = channelAccessor.Channel;
channel.ExchangeDeclare(exchange, exchangeType, durable: true);
var props = channel.CreateBasicProperties();
options?.Invoke(props);
channel.ConfirmSelect();
foreach (var data in datas)
channel.BasicPublish(exchange, routingKey, props, data);
channel.WaitForConfirmsOrDie();
}
private static TrackPushCompletedEvent TrackPushRecordDtoToEvent(TrackPushRecordDto log)
{
return new TrackPushCompletedEvent
{
RequestId = log.RequestId,
IsSuccess = log.IsSuccess,
Message = log.Message,
OperationMan = log.OperationMan,
PushTime = log.PushTime,
OptionType = log.OptionType,
IsManualPush = log.IsManualPush, //操作人不为系统用户,则认为是人推送
PushContent = log.PushContent,
OrderNo = log.OrderNo,
TrackStatus = log.TrackStatus,
TrackContent = log.TrackContent,
TrackTimeZone = log.TrackTimeZone,
TrackTime = log.TrackTime,
TrackPlace = log.TrackPlace,
TrackCode = log.TrackCode,
Extra = log.Extra,
InterfaceRelayData = log.InterfaceRelayData
};
}
}