diff --git a/src/SJZY.Track.Application.Contract/Services/IBroadcastingService.cs b/src/SJZY.Track.Application.Contract/Services/IBroadcastingService.cs
index 238f015b..91d34dec 100644
--- a/src/SJZY.Track.Application.Contract/Services/IBroadcastingService.cs
+++ b/src/SJZY.Track.Application.Contract/Services/IBroadcastingService.cs
@@ -20,9 +20,14 @@ public interface IBroadcastingService : ITransientDependency
///
///
///
- ///
void TrackChangePublicTopic(TrackChangeEto eto, string subSystemCode);
+ ///
+ /// 轨迹推送完成广播(推送完成回调)
+ ///
+ ///
+ void TrackPushCompletedPublicTopic(List list);
+
///
/// 轨迹推送完成广播(推送完成回调)
///
diff --git a/src/SJZY.Track.Application/Rabbit/RabbitClientBusExt.cs b/src/SJZY.Track.Application/Rabbit/RabbitClientBusExt.cs
new file mode 100644
index 00000000..55ff1ae3
--- /dev/null
+++ b/src/SJZY.Track.Application/Rabbit/RabbitClientBusExt.cs
@@ -0,0 +1,81 @@
+using System.Diagnostics;
+using BSI.Stack.Rabbit;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using RabbitMQ.Client;
+using Volo.Abp.DependencyInjection;
+
+namespace SJZY.Track.Application.Rabbit;
+
+///
+/// 支持发布确认模式
+///
+public class RabbitClientBusExt : RabbitClientBus, ISingletonDependency
+{
+ public RabbitClientBusExt(IServiceProvider sp, ILogger logger)
+ : base(sp, logger, sp.GetRequiredService>().CurrentValue)
+ {
+ }
+
+ public void PublishByConfirmSelect(
+ string exchange,
+ string routingKey,
+ byte[] data,
+ Action? options = null
+ )
+ {
+ using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
+ activity?.SetTag("kind", "publish");
+ var key = exchange + ":" + routingKey;
+ Lazy orAdd = Channels.GetOrAdd(key, (Func>) (_ => new Lazy(CreateModel)));
+ var basicProperties1 = orAdd.Value.CreateBasicProperties();
+
+ // 配置属性
+ if (options != null)
+ options(basicProperties1);
+ var model = orAdd.Value;
+
+ // 启用发布确认
+ model.ConfirmSelect();
+ var readOnlyMemory = (ReadOnlyMemory) data;
+ model.BasicPublish(exchange, routingKey, basicProperties1, readOnlyMemory);
+ model.WaitForConfirmsOrDie();
+ }
+
+ public void PublishByConfirmSelect(
+ string exchange,
+ string routingKey,
+ IEnumerable datas,
+ Action? options = null
+ )
+ {
+ using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
+ activity?.SetTag("kind", "publish");
+ var key = exchange + ":" + routingKey;
+ Lazy orAdd = Channels.GetOrAdd(key, (Func>) (_ => new Lazy(CreateModel)));
+ var basicProperties1 = orAdd.Value.CreateBasicProperties();
+
+ // 配置属性
+ if (options != null)
+ options(basicProperties1);
+ var model = orAdd.Value;
+
+ // 启用发布确认
+ model.ConfirmSelect();
+ foreach (var data in datas)
+ {
+ var readOnlyMemory = (ReadOnlyMemory) data;
+ model.BasicPublish(exchange, routingKey, basicProperties1, readOnlyMemory);
+ }
+ model.WaitForConfirmsOrDie();
+ }
+
+ private IConnection GetConnection()
+ {
+ var key = Connections.OrderBy((Func, int>) (q => q.Value)).Select((Func, IConnection>) (q => q.Key)).FirstOrDefault();
+ Connections.AddOrUpdate(key, (Func) (_ => 1), (Func) ((_, v) => v + 1));
+ return key;
+ }
+
+ private IModel CreateModel() => GetConnection().CreateModel();
+}
diff --git a/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs
index 8561d827..1ba4da4b 100644
--- a/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs
+++ b/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs
@@ -84,7 +84,7 @@ public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandl
// 推送广播
if (logs.First().IsToMq)
- logs.ForEach(log => _broadcastingService.TrackPushCompletedPublicTopic(BuildDto(log)));
+ _broadcastingService.TrackPushCompletedPublicTopic(logs.Select(BuildDto).ToList());
// 写入推送日志
await _trackPushRecordEsRepository.AddManyAsync(logs);
diff --git a/src/SJZY.Track.Application/Services/Broadcasting/BroadcastingService.cs b/src/SJZY.Track.Application/Services/Broadcasting/BroadcastingService.cs
index 7af7e83b..1723a226 100644
--- a/src/SJZY.Track.Application/Services/Broadcasting/BroadcastingService.cs
+++ b/src/SJZY.Track.Application/Services/Broadcasting/BroadcastingService.cs
@@ -1,9 +1,9 @@
using System.Text;
-using BSI.Stack.Rabbit;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services;
+using SJZY.Track.Application.Rabbit;
namespace SJZY.Track.Application.Services.Broadcasting;
@@ -12,9 +12,9 @@ namespace SJZY.Track.Application.Services.Broadcasting;
///
public class BroadcastingService : IBroadcastingService
{
- private readonly RabbitClientBus _rabbitClientBus;
+ private readonly RabbitClientBusExt _rabbitClientBus;
- public BroadcastingService(RabbitClientBus rabbitClientBus)
+ public BroadcastingService(RabbitClientBusExt rabbitClientBus)
{
_rabbitClientBus = rabbitClientBus;
}
@@ -64,15 +64,29 @@ public class BroadcastingService : IBroadcastingService
else
data.Option = 3;
- _rabbitClientBus.Publish(GlobalConst.TrackChangeExchange, $"TrackChange.{subSystemCode}",
- Encoding.UTF8.GetBytes(data.ToJson()));
+ _rabbitClientBus.PublishByConfirmSelect(GlobalConst.TrackChangeExchange, $"TrackChange.{subSystemCode}",
+ Encoding.UTF8.GetBytes(data.ToJson()), prop => { prop.Persistent = true; });
}
public void TrackChangePublicTopic(TrackChangeEto eto, string subSystemCode)
{
eto.Option = 2;
- _rabbitClientBus.Publish(GlobalConst.TrackChangeExchange, $"TrackChange.{subSystemCode}",
- Encoding.UTF8.GetBytes(eto.ToJson()));
+ _rabbitClientBus.PublishByConfirmSelect(GlobalConst.TrackChangeExchange, $"TrackChange.{subSystemCode}",
+ Encoding.UTF8.GetBytes(eto.ToJson()), prop => { prop.Persistent = true; });
+ }
+
+ ///
+ /// 轨迹推送完成广播(批量)
+ ///
+ ///
+ ///
+ public void TrackPushCompletedPublicTopic(List list)
+ {
+ var datas = list
+ .Select(TrackPushRecordDtoToEvent)
+ .Select(x => Encoding.UTF8.GetBytes(x.ToJson()));
+ var log = list.First();
+ _rabbitClientBus.PublishByConfirmSelect(GlobalConst.TrackPushExchange, $"TrackPush.{log.SubSystemCode}", datas, prop => { prop.Persistent = true; });
}
///
@@ -82,7 +96,24 @@ public class BroadcastingService : IBroadcastingService
///
public void TrackPushCompletedPublicTopic(TrackPushRecordDto log)
{
- var data = new TrackPushCompletedEvent
+ var data = TrackPushRecordDtoToEvent(log);
+ _rabbitClientBus.PublishByConfirmSelect(GlobalConst.TrackPushExchange, $"TrackPush.{log.SubSystemCode}",
+ Encoding.UTF8.GetBytes(data.ToJson()), prop => { prop.Persistent = true; });
+ }
+
+ ///
+ /// 轨迹推送失败广播
+ ///
+ ///
+ public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
+ {
+ //暂时使用推送完成模型,后续可能会出现有区分度的模型
+ TrackPushCompletedPublicTopic(log);
+ }
+
+ private static TrackPushCompletedEvent TrackPushRecordDtoToEvent(TrackPushRecordDto log)
+ {
+ return new TrackPushCompletedEvent
{
RequestId = log.RequestId,
IsSuccess = log.IsSuccess,
@@ -101,14 +132,5 @@ public class BroadcastingService : IBroadcastingService
TrackCode = log.TrackCode,
Extra = log.Extra
};
-
- _rabbitClientBus.Publish(GlobalConst.TrackPushExchange, $"TrackPush.{log.SubSystemCode}",
- Encoding.UTF8.GetBytes(data.ToJson()));
- }
-
- public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
- {
- //暂时使用推送完成模型,后续可能会出现有区分度的模型
- TrackPushCompletedPublicTopic(log);
}
}
diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
index 23a5cc5f..a3020ec5 100644
--- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
+++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
@@ -139,7 +139,7 @@ public class SjzyTrackApplicationModule : AbpModule
Console.WriteLine("-- 当前为VS本地环境,用内存存储和内存队列");
}
- context.Services.AddRabbitBoot(options =>
+ Action action = options =>
{
options.ConnectionString =
$"amqp://{configuration["RabbitMQ:UserName"]}:{configuration["RabbitMQ:Password"]}@{configuration["RabbitMQ:HostName"]}:{configuration["RabbitMQ:Port"]}";
@@ -178,7 +178,10 @@ public class SjzyTrackApplicationModule : AbpModule
}
}
};
- }, typeof(SjzyTrackApplicationModule).Assembly);
+ };
+
+ context.Services.Configure(action);
+ context.Services.AddRabbitBoot(action, typeof(SjzyTrackApplicationModule).Assembly);
context.Services.Configure(configuration.GetSection("TrackApp"));
context.Services.Configure(