RabbitMQ - потребитель, пропускающий событие Received и не получающий сообщения - PullRequest
0 голосов
/ 15 января 2020

У меня простой потребитель rabbitMQ, но я считаю, что он пропускает событие Received.

При отладке построчно он читает их, печатает их и выполняет все логические операции c, которые следуют за ним. но когда я запускаю его без отладки, это не так.

Я убедился, что в очереди есть сообщения:

enter image description here

Код потребителя:

namespace AutoMatcher.QueuesImpl
{
    public class RabbitMQImpl : IQueue
    {
        // 1. Message Received Event -- returns message
        // 2. private RabbitMq object implementation 
        // 3. under interfaces -- add new interfaces for queues that implements start listening and this event
        // 4. Installer object -- Registers private object as public interface in container
        private readonly IBotFactory _factory;
        public RabbitMQImpl(IBotFactory factory)
        {     
            _factory = factory;
        }
        public void StartListening()
        {  
            var factory = new ConnectionFactory()
            {
                HostName = "localhost",
                Port = 5672
            };
            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    var consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body;
                        //await Task.Yield();
                        var message = Encoding.UTF8.GetString(body);
                        Console.WriteLine(" [x] Received {0}", message);
                        var jsonMessage = JsonConvert.DeserializeObject<MessageWithoutUser>(message);
                        IBot bot = _factory.GetBot(jsonMessage);
                        bot.Execute(jsonMessage.MessageId, jsonMessage.UserId, jsonMessage.Likes, jsonMessage.Service, jsonMessage.Time);
                    };

                    channel.BasicConsume(queue: "messages",
                                         autoAck: true,
                                         consumer: consumer);
                }
            }
        }
    }
}

Я действительно понятия не имею, что происходит, какие-либо предложения? спасибо.

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Как уже упоминалось в комментариях, следующий раздел кода проблематичен c, поскольку после выхода из оператора using соединение закрывается и, следовательно, сообщение не принимается.

 using (var connection = factory.CreateConnection())
 {
      using (var channel = connection.CreateModel())
      {
            ....    
      }
 }

Вместо этого можно сохранить и соединение и канал как свойства.

public class RabbitMQImpl : IQueue
{
        private Connection _connection;
        private Channel _channel;

        private readonly IBotFactory _factory;

        public RabbitMQImpl(IBotFactory factory)
        {     
            _factory = factory;
        }

        public void StartListening()
        {  
            var factory = new ConnectionFactory()
            {
                HostName = "localhost",
                Port = 5672
            };
            _connection = factory.CreateConnection();
            _channel = connection.CreateModel();

            // your code

        }
}

Вы можете реализовать интерфейс IDisposable в классе RabbitMQImpl, чтобы закрыть соединение и канал, но вы должны иметь в виду, что «анти-паттерн» может быть создан быстро, см. этот комментарий

Надеюсь, это поможет.

0 голосов
/ 16 января 2020

Вызов перед классом.

var factory = new ConnectionFactory()
            {   HostName = "localhost",
                Port = 5672
            };

Сначала создайте фабрику, а затем присвойте _factory.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...