Exemplo n.º 1
0
        public override async Task SendAsync <T>(T message)
        {
            var messageHandlers = _messageHandlerProvider
                                  .GetHandlers <T>()
                                  .ToList();

            if (messageHandlers.Any())
            {
                foreach (var messageHandler in messageHandlers)
                {
                    var concreteType = typeof(IMessageHandler <>).MakeGenericType(typeof(T));
                    var method       = concreteType.GetMethod("HandAsync");
                    if (method != null)
                    {
                        await(Task) method.Invoke(messageHandler, new object[] { message });
                    }
                }
            }
            else
            {
                var messageName = MessageNameAttribute.GetNameOrDefault(message.GetType());
                _logger.LogWarning("No subscription for local memory message: {eventName}", messageName);
            }
            await Task.CompletedTask;
        }
Exemplo n.º 2
0
        public override async Task SendAsync <T>(T message)
        {
            var messageHandlers = _messageHandlerProvider
                                  .GetHandlers <T>()
                                  .ToList();

            if (messageHandlers.Any())
            {
                _logger.LogTrace("Enable diagnostic listeners before consume,name is {name}", DiagnosticListenerConstants.BeforeConsume);
                EventBusDiagnosticListener.TracingConsumeBefore(message);

                foreach (var messageHandler in messageHandlers)
                {
                    var concreteType = typeof(IMessageHandler <>).MakeGenericType(typeof(T));
                    var method       = concreteType.GetMethod("HandAsync");
                    if (method == null)
                    {
                        continue;
                    }
                    try
                    {
                        await(Task) method.Invoke(messageHandler, new object[] { message });
                    }
                    catch (Exception e)
                    {
                        var handlerType = messageHandler.GetType();
                        var messageType = message.GetType();
                        _logger.LogError("Message processing failure,message type is {messageType},handler type is {handlerType},error message is {errorMessage}",
                                         messageType, handlerType, e.Message);

                        _logger.LogTrace("Enable diagnostic listeners incorrect consume,name is {name}", DiagnosticListenerConstants.ErrorConsume);
                        EventBusDiagnosticListener.TracingConsumeError(message, handlerType, e.Message);
                    }
                }

                _logger.LogTrace("Enable diagnostic listeners after consume,name is {name}", DiagnosticListenerConstants.AfterConsume);
                EventBusDiagnosticListener.TracingConsumeAfter(message);
            }
            else
            {
                var messageName = MessageNameAttribute.GetNameOrDefault(message.GetType());
                _logger.LogWarning("No subscription for local memory message: {eventName}", messageName);

                _logger.LogTrace("Not subscribed to enable diagnostic listener,name is {name}", DiagnosticListenerConstants.NotSubscribed);
                EventBusDiagnosticListener.TracingNotSubscribed(message);
            }
            await Task.CompletedTask;
        }
        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;
        }
        private void TeyCreateMessageConsumer(Type eventType)
        {
            var(exchangeName, queueName) = GetExchangeNameAndQueueName(eventType);
            var key = $"{exchangeName}_{queueName}";

            lock (_lock)
            {
                if (!RabbitMqMessageConsumerDic.ContainsKey(key))
                {
                    var rabbitMqMessageConsumer = _rabbitMqMessageConsumerFactory.Create(
                        new RabbitMqExchangeDeclareConfigure(exchangeName, "direct", true),
                        new RabbitMqQueueDeclareConfigure(queueName));
                    rabbitMqMessageConsumer.OnMessageReceived(Consumer_Received);
                    RabbitMqMessageConsumerDic.TryAdd(key, rabbitMqMessageConsumer);
                }
                RabbitMqMessageConsumerDic.TryGetValue(key, out var rabbitMqMessageConsumer1);
                var eventName = MessageNameAttribute.GetNameOrDefault(eventType);
                rabbitMqMessageConsumer1?.BindAsync(eventName);
            }
        }
        private void TryCreateMessageConsumer(Type eventType)
        {
            var exchangeName = _options.Value.ExchangeName;
            var queueName    = MessageGroupAttribute.GetGroupOrDefault(eventType);
            var key          = $"{exchangeName}_{queueName}";

            lock (_lock)
            {
                if (!RabbitMqMessageConsumerDic.TryGetValue(key, out var rabbitMqMessageConsumer))
                {
                    rabbitMqMessageConsumer = _rabbitMqMessageConsumerFactory.Create(
                        new RabbitMqExchangeDeclareConfigure(exchangeName, "direct"),
                        new RabbitMqQueueDeclareConfigure(queueName));
                    rabbitMqMessageConsumer.OnMessageReceived(Consumer_Received);
                    RabbitMqMessageConsumerDic.TryAdd(key, rabbitMqMessageConsumer);
                }
                var eventName = MessageNameAttribute.GetNameOrDefault(eventType);
                rabbitMqMessageConsumer.BindAsync(eventName);
            }
        }
        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);
        }
        private void SubsManager_OnEventRemoved(object sender, Type messageType)
        {
            var exchangeName = _options.Value.ExchangeName;
            var queueName    = MessageGroupAttribute.GetGroupOrDefault(messageType);
            var key          = $"{exchangeName}_{queueName}";

            lock (_lock)
            {
                if (!RabbitMqMessageConsumerDic.TryGetValue(key, out var rabbitMqMessageConsumer))
                {
                    return;
                }
                var eventName = MessageNameAttribute.GetNameOrDefault(messageType);
                rabbitMqMessageConsumer.UnbindAsync(eventName);
                if (rabbitMqMessageConsumer.HasRoutingKeyBindingQueue())
                {
                    return;
                }
                rabbitMqMessageConsumer.Dispose();
                RabbitMqMessageConsumerDic.TryRemove(key, out _);
            }
        }
        private void SubsManager_OnEventRemoved(object sender, Type messageType)
        {
            var eventName = MessageNameAttribute.GetNameOrDefault(messageType);

            var(exchangeName, queueName) = GetExchangeNameAndQueueName(messageType);
            var key = $"{exchangeName}_{queueName}";

            lock (_lock)
            {
                if (!RabbitMqMessageConsumerDic.ContainsKey(key))
                {
                    return;
                }
                RabbitMqMessageConsumerDic.TryGetValue(key, out var rabbitMqMessageConsumer);
                rabbitMqMessageConsumer?.UnbindAsync(eventName);
                if (rabbitMqMessageConsumer != null && rabbitMqMessageConsumer.HasRoutingKeyBindingQueue())
                {
                    return;
                }
                rabbitMqMessageConsumer?.Dispose();
                RabbitMqMessageConsumerDic.TryRemove(key, out _);
            }
        }