Smit Jawale
Smit Jawale

Reputation: 63

How to get notified when a new message is added in RabbitMQ Queue?

I am new to RabbitMQ. I know that by using a while loop I can look for for the newly added messages in the Queue. But i don't want to go that way. I also tried EventingBasicConsumer Received event handler but that only triggers for the messages which are present when the subscriber code is running first time. Any newly added message does not trigger this code for me. Is there a way in which RibbitMQ will notify me if the queue has any new message. I want my Web Application to get notified by RabbitMQ whenever it has a new message.

Receiver : 
 public static class RabbitMQConsumer2
    {
        public static void Receive()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: "logs", type: "fanout");

                channel.QueueDeclare("AAA", true, false, false, null);
                channel.QueueBind(queue: "AAA",
                                  exchange: "logs",
                                  routingKey: "");

                Debug.WriteLine(" [*] Waiting for logs.");

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Debug.WriteLine(" [x] {0}", message);
                };
                channel.BasicConsume(queue: "AAA",
                                     noAck: true,
                                     consumer: consumer);

                Debug.WriteLine(" Press [enter] to exit.");
            }
        }
    }

Upvotes: 1

Views: 2509

Answers (2)

Cem Keskin
Cem Keskin

Reputation: 1

I created a console application and started with my web api from multiple startup projects area.

So, i aggre with @Vanlighty's answer.

You could try like this;

internal class Program
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory
        {
            Uri = new Uri("amqps://asdasd:[email protected]/asdasd")
        };

        using var connection = factory.CreateConnection();

        var channel = connection.CreateModel();
        channel.QueueDeclare("Test QueueDeclare", exclusive: false);

        var consumer = new EventingBasicConsumer(channel);
        channel.BasicConsume("Test QueueDeclare", true, consumer);

        consumer.Received += (sender, e) =>
        {
            Console.WriteLine(Encoding.UTF8.GetString(e.Body.Span));
        };
        Console.ReadLine();
    }
}

Upvotes: 0

Vanlightly
Vanlightly

Reputation: 1479

The problem is that you close the channel and connection immediately after calling BasicConsume (because it reaches the end of the scope of your usings). You need to kick-off a long-lived background thread where the connection and channel stay alive, then your receive handler will execute as soon as there are messages.

The eventing consumer is normally long lived, and better suited to a Windows Service or Console application. However, if you really need it in a web application and you really just need it to sit there in the background receiving messages then you can kick off a thread or long-lived task and anchor it in some static object so it doesn't die. But not knowing your use case I can't say that this is the best advice.

Upvotes: 1

Related Questions