Ejemplo n.º 1
0
        public void Subscribe(Type eventType, Type eventHandleType, string type = ExchangeType.Topic)
        {
            object attribute = eventType.GetCustomAttributes(typeof(EventBusAttribute), true).FirstOrDefault();

            if (attribute is EventBusAttribute attr)
            {
                string queue = attr.Queue ?? $"{ attr.Exchange }.{ eventType.Name }";
                if (!_persistentConnection.IsConnected)
                {
                    _persistentConnection.TryConnect();
                }
                IModel channel;
                #region snippet
                try
                {
                    channel = _persistentConnection.ExchangeDeclare(exchange: attr.Exchange, type: type);
                    channel.QueueDeclarePassive(queue);
                }
                catch
                {
                    channel = _persistentConnection.ExchangeDeclare(exchange: attr.Exchange, type: type);
                    channel.QueueDeclare(queue: queue,
                                         durable: true,
                                         exclusive: false,
                                         autoDelete: false,
                                         arguments: null);
                }
                #endregion
                channel.QueueBind(queue, attr.Exchange, attr.RoutingKey, null);
                channel.BasicQos(0, 1, false);
                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
                consumer.Received += async(model, ea) =>
                {
                    string body  = Encoding.UTF8.GetString(ea.Body);
                    bool   isAck = false;
                    try
                    {
                        await ProcessEvent(body, eventType, eventHandleType);

                        channel.BasicAck(ea.DeliveryTag, multiple: false);
                        isAck = true;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(new EventId(ex.HResult), ex, ex.Message);
                        await Task.Delay((int)_persistentConnection.Configuration.ConsumerFailRetryInterval.TotalMilliseconds).ContinueWith(p => channel.BasicNack(ea.DeliveryTag, false, true));
                    }
                    finally
                    {
                        _eventHandlerFactory?.SubscribeEvent(new EventBusArgs(_persistentConnection.Endpoint, ea.Exchange, queue, attr.RoutingKey, type, _persistentConnection.Configuration.ClientProvidedName, body));
                        _logger.Information($"RabbitMQEventBus\t{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss")}\t{isAck}\t{ea.Exchange}\t{ea.RoutingKey}\t{body}");
                    }
                };
                channel.CallbackException += (sender, ex) =>
                {
                };
                channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);
            }
        }
Ejemplo n.º 2
0
        public void Subscribe(Type eventType, string type = ExchangeType.Topic)
        {
            var attributes        = eventType.GetCustomAttributes(typeof(EventBusAttribute), true);
            var millisecondsDelay = (int?)_persistentConnection?.Configuration?.ConsumerFailRetryInterval.TotalMilliseconds ?? 1000;

            foreach (var attribute in attributes)
            {
                if (attribute is EventBusAttribute attr)
                {
                    string queue = attr.Queue ?? (_persistentConnection.Configuration.Prefix == QueuePrefixType.ExchangeName
                        ? $"{ attr.Exchange }.{ eventType.Name }"
                        : $"{_persistentConnection.Configuration.ClientProvidedName}.{ eventType.Name }");
                    if (!_persistentConnection.IsConnected)
                    {
                        _persistentConnection.TryConnect();
                    }
                    IModel channel;
                    #region snippet
                    var arguments = new Dictionary <string, object>();

                    #region 死信队列设置
                    if (_persistentConnection.Configuration.DeadLetterExchange.Enabled)
                    {
                        string deadExchangeName = $"{_persistentConnection.Configuration.DeadLetterExchange.ExchangeNamePrefix}{_persistentConnection.Configuration.DeadLetterExchange.CustomizeExchangeName ?? attr.Exchange}{_persistentConnection.Configuration.DeadLetterExchange.ExchangeNameSuffix}";
                        string deadQueueName    = $"{_persistentConnection.Configuration.DeadLetterExchange.ExchangeNamePrefix}{queue}{_persistentConnection.Configuration.DeadLetterExchange.ExchangeNameSuffix}";
                        IModel dlxChannel;
                        try
                        {
                            dlxChannel = _persistentConnection.ExchangeDeclare(exchange: deadExchangeName, type: type);
                            dlxChannel.QueueDeclarePassive(deadQueueName);
                        }
                        catch
                        {
                            dlxChannel = _persistentConnection.ExchangeDeclare(exchange: deadExchangeName, type: type);
                            dlxChannel.QueueDeclare(queue: deadQueueName,
                                                    durable: true,
                                                    exclusive: false,
                                                    autoDelete: false,
                                                    arguments: null);
                        }
                        dlxChannel.QueueBind(deadQueueName, deadExchangeName, attr.RoutingKey, null);
                        arguments.Add("x-dead-letter-exchange", deadExchangeName);
                    }
                    #endregion

                    try
                    {
                        channel = _persistentConnection.ExchangeDeclare(exchange: attr.Exchange, type: type);
                        channel.QueueDeclarePassive(queue);
                    }
                    catch
                    {
                        channel = _persistentConnection.ExchangeDeclare(exchange: attr.Exchange, type: type);
                        if (_persistentConnection.Configuration.MessageTTL != null && _persistentConnection.Configuration.MessageTTL > 0)
                        {
                            arguments.Add("x-message-ttl", _persistentConnection.Configuration.MessageTTL);
                        }
                        channel.QueueDeclare(queue: queue,
                                             durable: true,
                                             exclusive: false,
                                             autoDelete: false,
                                             arguments: arguments);
                    }
                    #endregion
                    channel.QueueBind(queue, attr.Exchange, attr.RoutingKey, null);
                    channel.BasicQos(0, _persistentConnection.Configuration.PrefetchCount, false);
                    EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
                    consumer.Received += async(model, ea) =>
                    {
                        string body  = Encoding.UTF8.GetString(ea.Body.ToArray());
                        bool   isAck = false;
                        try
                        {
                            await ProcessEvent(body, eventType, ea);

                            //不确定是否需要改变Multiple是否需要改为true
                            channel.BasicAck(ea.DeliveryTag, multiple: false);
                            isAck = true;
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(new EventId(ex.HResult), ex, ex.Message);
                        }
                        finally
                        {
                            _eventHandlerFactory?.SubscribeEvent(new EventBusArgs(_persistentConnection.Endpoint, ea.Exchange, queue, attr.RoutingKey, type, _persistentConnection.Configuration.ClientProvidedName, body, isAck));
                            _logger.WriteLog(_persistentConnection.Configuration.Level, $"{DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss")}\t{isAck}\t{ea.Exchange}\t{ea.RoutingKey}\t{body}");
                            if (!isAck)
                            {
                                await Task.Delay(millisecondsDelay);

                                channel.BasicNack(ea.DeliveryTag, false, true);
                            }
                        }
                    };
                    channel.CallbackException += (sender, ex) =>
                    {
                        _logger.LogError(new EventId(ex.Exception.HResult), ex.Exception, ex.Exception.Message);
                    };
                    channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);
                }
            }
        }