Ejemplo n.º 1
0
        public void Publish(Message message)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
            {
                _logger.LogWarning(ex.ToString());
            });

            using (var channel = _persistentConnection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: _brokerName, type: ExchangeType.Direct, durable: true);
                DefineCommandQueue();
                var body = message.ToMessage();
                policy.Execute(() =>
                {
                    channel.BasicPublish(exchange: _brokerName,
                                         routingKey: _routingKey,
                                         basicProperties: null,
                                         body: body);
                });
            }
        }
        private IModel CreateConsumerChannel()
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            _logger.LogTrace("Creating RabbitMQ consumer channel");

            var channel = _persistentConnection.CreateModel();

            channel.ExchangeDeclare(exchange: BrokerName, type: "direct");

            channel.QueueDeclare(queue: _queueName, durable: true, exclusive: false, autoDelete: false,
                                 arguments: null);

            channel.CallbackException += (sender, ea) =>
            {
                _logger.LogWarning(ea.Exception, "Recreating RabbitMQ consumer channel");

                _consumerChannel.Dispose();
                _consumerChannel = CreateConsumerChannel();
                StartBasicConsume();
            };

            return(channel);
        }
Ejemplo n.º 3
0
 public Task BindAsync(string routingKey)
 {
     if (!_persistentConnection.IsConnected)
     {
         _persistentConnection.TryConnect();
     }
     using (var channel = _persistentConnection.CreateModel())
     {
         channel.ExchangeDeclare(
             exchange: ExchangeDeclare.ExchangeName,
             type: ExchangeDeclare.Type,
             durable: ExchangeDeclare.Durable,
             autoDelete: ExchangeDeclare.AutoDelete,
             arguments: ExchangeDeclare.Arguments);
         channel.QueueDeclare(queue: QueueDeclare.QueueName,
                              durable: QueueDeclare.Durable,
                              exclusive: QueueDeclare.Exclusive,
                              autoDelete: QueueDeclare.AutoDelete,
                              arguments: QueueDeclare.Arguments);
         channel.QueueBind(queue: QueueDeclare.QueueName,
                           exchange: ExchangeDeclare.ExchangeName,
                           routingKey: routingKey);
         BindingQueueRoutingKeys.TryAdd(routingKey, QueueDeclare.QueueName);
     }
     return(Task.CompletedTask);
 }
Ejemplo n.º 4
0
        /// <inheritdoc />
        public void Publish(IIntegrationEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
            {
                _logger.LogWarning(ex.ToString());
            });

            using (var channel = _persistentConnection.CreateModel())
            {
                var eventName = @event.GetType().Name;
                channel.ExchangeDeclare(exchange: _brokerName, type: "direct");

                var message = JsonConvert.SerializeObject(@event);
                var body    = Encoding.UTF8.GetBytes(message);
                policy.Execute(() =>
                {
                    channel.BasicPublish(exchange: _brokerName, routingKey: eventName, basicProperties: null, body: body);
                });
            }
        }
        public bool Publish(BusEvent @event)
        {
            if ((!IsConnected) && !_persistentConnection.TryConnect())
            {
                return(false);
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                var eventName = @event.GetType().Name;

                channel.ExchangeDeclare(ConnectionParams.ExchangeName, "direct");

                var messageBody = Helpers.SerializationHelper.Serialize(@event);

                var properties = channel.CreateBasicProperties();
                properties.DeliveryMode = 1;

                channel.BasicPublish(ConnectionParams.ExchangeName,
                                     eventName,
                                     true,
                                     properties,
                                     messageBody
                                     );
            }

            return(true);
        }
Ejemplo n.º 6
0
        public void Publish(IntegrationEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                var eventName = @event.GetType().Name;

                channel.ExchangeDeclare(exchange: BrokerName,
                                        type: "direct");

                var message = JsonConvert.SerializeObject(@event);
                var body    = Encoding.UTF8.GetBytes(message);

                var properties = channel.CreateBasicProperties();
                properties.DeliveryMode = 2; // persistent

                channel.BasicPublish(exchange: BrokerName,
                                     routingKey: eventName,
                                     mandatory: true,
                                     basicProperties: properties,
                                     body: body);
            }
        }
 private void RenewConnectionIfNeeded()
 {
     if (!_rabbitMqPersistentConnection.IsConnected)
     {
         _rabbitMqPersistentConnection.TryConnect();
     }
 }
Ejemplo n.º 8
0
        public void Publish(IntegrationEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = RetryPolicy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
            {
            });

            using (var channel = _persistentConnection.CreateModel())
            {
                var eventName = @event.GetType()
                                .Name;

                var message = JsonConvert.SerializeObject(@event);
                var body    = Encoding.UTF8.GetBytes(message);

                policy.Execute(() =>
                {
                    var properties          = channel.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent

                    channel.BasicPublish(exchange: BROKER_NAME,
                                         routingKey: eventName,
                                         mandatory: true,
                                         basicProperties: properties,
                                         body: body);
                });
            }
        }
Ejemplo n.º 9
0
        public void Publish(IntegrationEvent @event, Dictionary <string, object> parameters)
        {
            string eventType = @event.GetType().Name;

            (string exchange, string routingKey) = PublishHelper(eventType: eventType
                                                                 , publishAsError: @event.PublishAsError
                                                                 , parameters);

            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            // ReSharper disable once AccessToStaticMemberViaDerivedType
            RetryPolicy policy = RetryPolicy.Handle <BrokerUnreachableException>()
                                 .Or <SocketException>()
                                 .WaitAndRetry(_options.RetryCount
                                               , retryAttempt => TimeSpan.FromSeconds(Math.Pow(2
                                                                                               , retryAttempt))
                                               , (ex, time) => { _logger.LogWarning(ex.ToString()); });

            using (IModel channel = _persistentConnection.CreateModel())
            {
                string message = JsonConvert.SerializeObject(@event, new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                });
                byte[] body = Encoding.UTF8.GetBytes(message);
                channel.BasicAcks   += BasicAcks;
                channel.BasicReturn += BasicReturn;
                channel.ConfirmSelect();

                policy.Execute(() =>
                {
                    IBasicProperties basicProperties = channel.CreateBasicProperties();
                    basicProperties.Persistent       = true;
                    basicProperties.ContentType      = "application/json";                               //MediaTypeNames.Application.Json;
                    basicProperties.Type             = eventType;
                    basicProperties.AppId            = _options.AppId;
                    basicProperties.UserId           = _options.UserName;
                    _logger.LogDebug("Publishing {EventType} message to exchange {Exchange} with {RoutingKey} as {Body}"
                                     , eventType
                                     , exchange
                                     , routingKey
                                     , message);
                    channel.BasicPublish(exchange: exchange
                                         , routingKey: routingKey
                                         , mandatory: true
                                         , basicProperties: basicProperties
                                         , body: body);
                    if (_options.WaitForConfirmsOrDieExists)
                    {
                        channel.WaitForConfirmsOrDie(_options.WaitForConfirmsOrDie);
                    }
                });
            }
        }
Ejemplo n.º 10
0
 private void TryCreateExchangeAndQueue()
 {
     if (!_persistentConnection.IsConnected)
     {
         _persistentConnection.TryConnect();
     }
     using (var channel = _persistentConnection.CreateModel())
     {
         ExchangeDeclare.Declare(channel);
         QueueDeclare.Declare(channel);
     }
 }
        public Task Publish <TIntegrationEvent>(TIntegrationEvent @event)
            where TIntegrationEvent : IIntegrationEvent
        {
            var eventName = @event.GetType().Name;

            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = Policy
                         .Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry
                         (
                _retryCount,
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
                         );

            policy.Execute(() =>
            {
                using (var producerChannel = _persistentConnection.CreateModel())
                {
                    producerChannel.ExchangeDeclare
                    (
                        type: _exchangeType,
                        exchange: _brokerName,
                        autoDelete: false,
                        durable: true
                    );

                    var message = JsonConvert.SerializeObject(@event);
                    var body    = Encoding.UTF8.GetBytes(message);

                    var properties          = producerChannel.CreateBasicProperties();
                    properties.ContentType  = "application/json";
                    properties.DeliveryMode = 2; // persistent
                    producerChannel.BasicPublish
                    (
                        routingKey: eventName,
                        exchange: _brokerName,
                        mandatory: true,
                        body: body,
                        basicProperties: properties
                    );
                }
            });

            return(Task.CompletedTask);
        }
Ejemplo n.º 12
0
        private void SubsManager_OnEventRemoved(object sender, string eventName)
        {
            if (!PersistentConnection.IsConnected)
            {
                PersistentConnection.TryConnect();
            }

            using var channel = PersistentConnection.CreateModel();
            channel.QueueUnbind(QueueName, ExchangeDeclareParameters.ExchangeName, eventName);

            if (!SubsManager.IsEmpty)
            {
                return;
            }
            QueueName = string.Empty;
            ConsumerChannel?.Close();
        }
Ejemplo n.º 13
0
 public Task BindAsync(string routingKey)
 {
     if (!_persistentConnection.IsConnected)
     {
         _persistentConnection.TryConnect();
     }
     using (var channel = _persistentConnection.CreateModel())
     {
         ExchangeDeclare.Declare(channel);
         QueueDeclare.Declare(channel);
         channel.QueueBind(queue: QueueDeclare.QueueName,
                           exchange: ExchangeDeclare.ExchangeName,
                           routingKey: routingKey);
         BindingQueueRoutingKeys.TryAdd(routingKey, QueueDeclare.QueueName);
     }
     return(Task.CompletedTask);
 }
Ejemplo n.º 14
0
        public void Publish <TEvent>(TEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
            {
                _logger.LogWarning(ex, "Could not publish event: {EventType} after {Timeout}s ({ExceptionMessage})",
                                   typeof(TEvent).Name,
                                   $"{time.TotalSeconds:n1}",
                                   ex.Message
                                   );
            });

            using (var channel = _persistentConnection.CreateModel())
            {
                var exchangeName = GetExchangeName <TEvent>();

                channel.ExchangeDeclare(exchange: exchangeName, type: "fanout");

                var message = JsonConvert.SerializeObject(@event);
                var body    = Encoding.UTF8.GetBytes(message);

                policy.Execute(() =>
                {
                    // ReSharper disable AccessToDisposedClosure
                    var properties = channel.CreateBasicProperties();

                    properties.DeliveryMode = 2; // persistent

                    channel.BasicPublish(exchange: exchangeName,
                                         routingKey: string.Empty,
                                         mandatory: true,
                                         basicProperties: properties,
                                         body: body);

                    _logger.LogInformation("Message {EventType} published to exchange {Exchange}.",
                                           typeof(TEvent).Name, exchangeName);
                    // ReSharper restore AccessToDisposedClosure
                });
            }
        }
Ejemplo n.º 15
0
        private void SubsManager_OnEventRemoved(object sender, string eventName)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                channel.QueueUnbind(queue: _options.QueueName,
                                    exchange: _options.BrokerName,
                                    routingKey: eventName);
                if (_subsManager.IsEmpty)
                {
                    _consumerChannel.Close();
                }
            }
        }
        private void RegistrationManagerOnMessageRemoved(object sender, string messageName)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (IModel channel = _persistentConnection.CreateModel())
            {
                channel.QueueUnbind(_queueName, BrokerName, messageName);

                if (_messageBusRegistrationsManager.IsEmpty)
                {
                    _queueName = string.Empty;
                    _consumerChannel.Close();
                }
            }
        }
Ejemplo n.º 17
0
        public void Publish(IntegrationEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var eventName = @event.GetType().Name;

            _logger.LogTrace(
                "Creating RabbitMQ channel to publish event: {EventId} ({EventName})",
                @event.Id, eventName);

            using (var channel = _persistentConnection.CreateModel())
            {
                // TODO: concider Publisher confirms - not possible with
                // TODO: disposable channels though
                //channel.ConfirmSelect();
                //channel.BasicNacks += (model, ea) =>
                //{
                //    _logger.LogTrace("Event {EventName} with id = {EventId} publish failure",
                //        eventName, @event.Id);
                //};

                var message = System.Text.Json
                              .JsonSerializer.Serialize(@event, @event.GetType());
                var body = Encoding.UTF8.GetBytes(message);

                _resillientPublishPolicyAction(() =>
                {
                    var properties          = channel.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent message

                    _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id);

                    channel.BasicPublish(
                        exchange: _exchangeName,
                        routingKey: eventName,
                        mandatory: true,
                        basicProperties: properties,
                        body: body);
                });
            }
        }
Ejemplo n.º 18
0
        public async Task InitializeConsumersChannelsAsync()
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            _logger.LogInformation("Initializing consumer");

            var consumerStarts = new List <Task>();

            for (int i = 0; i < _rabbitMqEventBusOptions.ConsumersCount; i++)
            {
                var channel = _persistentConnection.CreateModel();
                consumerStarts.Add(Task.Run(() => InitializeConsumer(channel)));
            }

            await Task.WhenAll(consumerStarts);
        }
Ejemplo n.º 19
0
        /// <summary>
        ///     used to publish event.
        ///     this will resilient by default thanks to polly.
        /// </summary>
        /// <param name="event">
        ///     Event to publish.
        /// </param>
        public void Publish(IntegrationEvent @event)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(
                _retryCount,
                retryAttempt =>
                TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                (ex, time) => { _logger.LogWarning(ex.ToString()); });

            using (var channel = _persistentConnection.CreateModel())
            {
                var eventName = @event.GetType().Name;

                // to guarantee exchange exists.
                // type direct means it will directly use bindingkey or routingkey instead of queue name.
                channel.ExchangeDeclare(BrokerName,
                                        "direct");

                var message = JsonConvert.SerializeObject(@event);
                var body    = Encoding.UTF8.GetBytes(message);

                policy.Execute(() =>
                {
                    // ReSharper disable once AccessToDisposedClosure
                    var properties          = channel.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent

                    // ReSharper disable once AccessToDisposedClosure
                    channel.BasicPublish(BrokerName,
                                         eventName,
                                         true,
                                         properties,
                                         body);
                });
            }
        }
Ejemplo n.º 20
0
        private void SubsManager_OnEventRemoved(object sender, string eventName)
        {
            if (!persistentConnection.IsConnected)
            {
                persistentConnection.TryConnect();
            }

            using (var channel = persistentConnection.CreateModel())
            {
                channel.QueueUnbind(queue: queueName,
                                    exchange: BROKER_NAME,
                                    routingKey: eventName);

                if (subsManager.IsEmpty)
                {
                    queueName = string.Empty;
                    consumerChannel.Close();
                }
            }
        }
        private void SubsManager_OnEventRemoved(object sender, string eventName)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                channel.QueueUnbind(_queueName, _brokerName, eventName);

                if (!_subsManager.IsEmpty)
                {
                    return;
                }

                _queueName = string.Empty;
                _consumerChannel.Close();
            }
        }
Ejemplo n.º 22
0
        public async Task PublishAsync <T>(T @event) where T : Event
        {
            var eventName = @event.GetType().Name;

            _logger.LogInformation($"Publishing {eventName} with id: {@event.Id}");
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using var channel = _persistentConnection.CreateModel();
            var props = channel.CreateBasicProperties();

            props.CorrelationId = @event.Id.ToString();
            channel.BasicPublish(
                _options.ExchangeName,
                routingKey: eventName,
                basicProperties: props,
                body: Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event)));
            _logger.LogInformation($"Event published");
        }
        public override async Task SendAsync <T>(T message)
        {
            _logger.LogTrace("Enable diagnostic listeners before publishing,name is {name}", DiagnosticListenerConstants.BeforePublish);
            EventBusDiagnosticListener.TracingPublishBefore(message);

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(retryAttempt), (ex, time) =>
            {
                _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", message.Id, $"{time.TotalSeconds:n1}", ex.Message);
            });

            var eventName = MessageNameAttribute.GetNameOrDefault(message.GetType());
            var data      = message.ToJson();
            var body      = Encoding.UTF8.GetBytes(data).AsMemory();

            var exchangeName = _options.Value.ExchangeName;

            policy.Execute(() =>
            {
                if (!_persistentConnection.IsConnected)
                {
                    _persistentConnection.TryConnect();
                }

                using (var channel = _persistentConnection.CreateModel())
                {
                    var model = channel;
                    _logger.LogTrace("Declaring RabbitMQ exchange {ExchangeName} to publish event: {EventId}", exchangeName, message.Id);
                    model.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true, autoDelete: false,
                                          arguments: new ConcurrentDictionary <string, object>());

                    var properties          = model.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent
                    _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", message.Id);
                    model.BasicPublish(
                        exchange: exchangeName,
                        routingKey: eventName,
                        mandatory: true,
                        basicProperties: properties,
                        body: body);
                }
            });

            _logger.LogTrace("Enable diagnostic listeners after publishing,name is {name}", DiagnosticListenerConstants.AfterPublish);
            EventBusDiagnosticListener.TracingPublishAfter(message);
            await Task.CompletedTask;
        }
Ejemplo n.º 24
0
        private void SubscribeToRabbitMq <T>(Subscription <T> subscription) where T : Event
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            _logger.LogInformation($"Binding queue to exchange with event {subscription.EventName}");
            using var channel = _persistentConnection.CreateModel();
            channel.QueueBind(
                queue: _rabbitMqEventBusOptions.QueueName,
                exchange: _rabbitMqEventBusOptions.ExchangeName,
                routingKey: subscription.EventName
                );
            _logger.LogInformation($"Queue successfully bound to exchange with event {subscription.EventName}");
        }
Ejemplo n.º 25
0
        protected override Task PublishAsync(Type eventType, IntegrationEvent eventDate)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }
            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
            {
                _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", eventDate.Id, $"{time.TotalSeconds:n1}", ex.Message);
            });

            var eventName = EventNameAttribute.GetNameOrDefault(eventType);

            _logger.LogTrace("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", eventDate.Id, eventName);

            using (var channel = _persistentConnection.CreateModel())
            {
                _logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", eventDate.Id);
                var message = JsonConvert.SerializeObject(eventDate);
                var body    = Encoding.UTF8.GetBytes(message);

                var model        = channel;
                var exchangeName = GetPublishConfigure();
                model.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true);
                policy.Execute(() =>
                {
                    var properties          = model.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent

                    _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", eventDate.Id);

                    model.BasicPublish(
                        exchange: exchangeName,
                        routingKey: eventName,
                        mandatory: true,
                        basicProperties: properties,
                        body: body);
                });
            }
            return(Task.CompletedTask);
        }
        public override Task SendAsync <T>(T message)
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }
            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(retryAttempt), (ex, time) =>
            {
                _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", message.Id, $"{time.TotalSeconds:n1}", ex.Message);
            });

            var eventName = MessageNameAttribute.GetNameOrDefault(message.GetType());

            _logger.LogTrace("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", message.Id, eventName);

            using (var channel = _persistentConnection.CreateModel())
            {
                _logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", message.Id);
                var data = JsonConvert.SerializeObject(message);
                var body = Encoding.UTF8.GetBytes(data).AsMemory();

                var model        = channel;
                var exchangeName = _options.Value.RabbitMqPublishConfigure.GetExchangeName() ?? RabbitMqConst.DefaultExchangeName;
                model.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true, autoDelete: false, arguments: new ConcurrentDictionary <string, object>());
                policy.Execute(() =>
                {
                    var properties          = model.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent
                    _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", message.Id);
                    model.BasicPublish(
                        exchange: exchangeName,
                        routingKey: eventName,
                        mandatory: true,
                        basicProperties: properties,
                        body: body);
                });
            }
            return(Task.CompletedTask);
        }
        /// <summary>
        /// 取消配置广播模式队列和对应动态事件
        /// </summary>
        /// <typeparam name="TH"></typeparam>
        /// <param name="eventName"></param>
        /// <param name="queueName"></param>
        public void UnListeningDynamic <TH>(string eventName, string queueName)
            where TH : IDynamicIntegrationEventHandler
        {
            _subsManager.RemoveDynamicListener <TH>(eventName);
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            using (var channel = _persistentConnection.CreateModel())
            {
                channel.QueueUnbind(queue: eventName,
                                    exchange: _fanoutExchangeName,
                                    routingKey: eventName);

                if (_subsManager.IsEmpty)
                {
                    _listenChannel.Close();
                }

                channel.Close();
            }
        }