@ -10,7 +10,6 @@ using Volo.Abp.RabbitMQ;
using RabbitMQ.Client ;
using RabbitMQ.Client ;
using RabbitMQ.Client.Events ;
using RabbitMQ.Client.Events ;
using Volo.Abp.Collections ;
using Volo.Abp.Collections ;
using Volo.Abp.EventBus.Local ;
using Volo.Abp.Threading ;
using Volo.Abp.Threading ;
namespace Volo.Abp.EventBus.Distributed.RabbitMq
namespace Volo.Abp.EventBus.Distributed.RabbitMq
@ -29,27 +28,44 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
protected IRabbitMqSerializer Serializer { get ; }
protected IRabbitMqSerializer Serializer { get ; }
protected ConcurrentDictionary < Type , List < IEventHandlerFactory > > HandlerFactories { get ; } //TODO: Accessing to the List<IEventHandlerFactory> may not be thread-safe!
protected ConcurrentDictionary < Type , List < IEventHandlerFactory > > HandlerFactories { get ; } //TODO: Accessing to the List<IEventHandlerFactory> may not be thread-safe!
protected ConcurrentDictionary < string , Type > EventTypes { get ; }
protected ConcurrentDictionary < string , Type > EventTypes { get ; }
protected IModel ConsumerChannel ;
protected IHybridServiceScopeFactory ServiceScopeFactory { get ; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get ; }
protected IRabbitMqMessageConsumerFactory MessageConsumerFactory { get ; }
protected IRabbitMqMessageConsumer Consumer { get ; }
public RabbitMqDistributedEventBus (
public RabbitMqDistributedEventBus (
IOptions < RabbitMqDistributedEventBusOptions > options ,
IOptions < RabbitMqDistributedEventBusOptions > options ,
IConnectionPool connectionPool ,
IConnectionPool connectionPool ,
IRabbitMqSerializer serializer ,
IRabbitMqSerializer serializer ,
IHybridServiceScopeFactory serviceScopeFactory ,
IHybridServiceScopeFactory serviceScopeFactory ,
IOptions < DistributedEventBusOptions > distributedEventBusOptions )
IOptions < DistributedEventBusOptions > distributedEventBusOptions ,
IRabbitMqMessageConsumerFactory messageConsumerFactory )
{
{
ConnectionPool = connectionPool ;
ConnectionPool = connectionPool ;
Serializer = serializer ;
Serializer = serializer ;
ServiceScopeFactory = serviceScopeFactory ;
ServiceScopeFactory = serviceScopeFactory ;
MessageConsumerFactory = messageConsumerFactory ;
DistributedEventBusOptions = distributedEventBusOptions . Value ;
DistributedEventBusOptions = distributedEventBusOptions . Value ;
RabbitMqDistributedEventBusOptions = options . Value ;
RabbitMqDistributedEventBusOptions = options . Value ;
HandlerFactories = new ConcurrentDictionary < Type , List < IEventHandlerFactory > > ( ) ;
HandlerFactories = new ConcurrentDictionary < Type , List < IEventHandlerFactory > > ( ) ;
EventTypes = new ConcurrentDictionary < string , Type > ( ) ;
EventTypes = new ConcurrentDictionary < string , Type > ( ) ;
ConsumerChannel = CreateConsumerChannel ( ) ;
Subscribe ( DistributedEventBusOptions . Handlers ) ;
Subscribe ( DistributedEventBusOptions . Handlers ) ;
Consumer = MessageConsumerFactory . Create (
new ExchangeDeclareConfiguration (
RabbitMqDistributedEventBusOptions . ExchangeName ,
type : "direct"
) ,
new QueueDeclareConfiguration (
RabbitMqDistributedEventBusOptions . ClientName ,
durable : true ,
exclusive : false ,
autoDelete : false
)
) ;
Consumer . OnMessageReceived ( ProcessEventAsync ) ;
}
}
protected virtual void Subscribe ( ITypeList < IEventHandler > handlers )
protected virtual void Subscribe ( ITypeList < IEventHandler > handlers )
@ -73,41 +89,6 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
}
}
}
}
private IModel CreateConsumerChannel ( )
{
//TODO: Support multiple connection (and consumer)?
var channel = ConnectionPool . Get ( ) . CreateModel ( ) ;
channel . ExchangeDeclare (
exchange : RabbitMqDistributedEventBusOptions . ExchangeName ,
type : "direct"
) ;
channel . QueueDeclare (
queue : RabbitMqDistributedEventBusOptions . ClientName ,
durable : true ,
exclusive : false ,
autoDelete : false ,
arguments : null
) ;
var consumer = new EventingBasicConsumer ( channel ) ;
consumer . Received + = async ( model , ea ) = > { await ProcessEventAsync ( channel , ea ) ; } ;
channel . BasicConsume (
queue : RabbitMqDistributedEventBusOptions . ClientName ,
autoAck : false ,
consumer : consumer
) ;
channel . CallbackException + = ( sender , ea ) = >
{
ConsumerChannel . Dispose ( ) ;
ConsumerChannel = CreateConsumerChannel ( ) ;
} ;
return channel ;
}
private async Task ProcessEventAsync ( IModel channel , BasicDeliverEventArgs ea )
private async Task ProcessEventAsync ( IModel channel , BasicDeliverEventArgs ea )
{
{
var eventName = ea . RoutingKey ;
var eventName = ea . RoutingKey ;