0

I have a simple rabbitMQ consumer but I believe that he is skipping the Received event.

When debugging line by line, it reads them, prints them and does all the logic that follows it. but when I run it without debug, it doesn't.

I made sure there are messages in the queue:

enter image description here

Consumer Code:

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);
                }
            }
        }
    }
}

I really have no idea what's going on, any suggestions? thanks.

Roman Sterlin
  • 1,485
  • 3
  • 10
  • 25
  • 2
    I think the problem you have is that your channel get disposed before you received a message. In debug mode you are slow enough to make it work. – Darem Jan 16 '20 at 08:47
  • Darem, post this I will approve this, I removed the using statement and closed the channel myself as soon as it closes the connection and it worked...REALY WEIRED. how is it closing the channel before it is done, its even in their tutorial – Roman Sterlin Jan 16 '20 at 17:00

2 Answers2

1

As mentioned in the comments the following code section is problematic, because after leaving the using statement the connection is closed and therefore no message is ever received.

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

Instead, you could save both the connection and the channel as properties.

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

        }
}

You could implement the IDisposable interface in the class RabbitMQImpl to close the connection and the channel, but you should keep in mind that an "anti-pattern" can be created quickly, see this comment

I hope this helps.

Darem
  • 1,689
  • 1
  • 17
  • 37
0

Call before class contrutor.

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

First create factory and then assign to _factory.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Gaurav
  • 11
  • 2