1. 程式人生 > 其它 >訊息中介軟體RabbitMQ(二)

訊息中介軟體RabbitMQ(二)

上篇文章主要說大概邏輯,這篇就文章用程式碼驗證細節。

1、當交換機為Direct型別,當多個相同路由key和佇列連線時,傳送訊息時,佇列是否都會收到訊息? 答案是肯定的。

傳送端:

using (IConnection con = conFactory.CreateConnection())//建立連線物件
{
    using (IModel channel = con.CreateModel())//建立連線會話物件
    {
        channel.QueueDeclare(queue1, false, false, false, null);
        channel.QueueDeclare(queue2, 
false, false, false, null); channel.QueueDeclare(queue3, false, false, false, null); channel.ExchangeDeclare(exchange1, ExchangeType.Direct); channel.QueueBind(queue1, exchange1, routingKey1); channel.QueueBind(queue2, exchange1, routingKey2); channel.QueueBind(queue3, exchange1, routingKey2);
while (true) { Console.WriteLine("訊息內容:"); var message = Console.ReadLine(); byte[] body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange1, routingKey2, null, body); channel.BasicPublish(exchange1, routingKey1,
null, body); Console.WriteLine("成功傳送訊息:" + message); } } }

消費端:

using (IConnection conn = connFactory.CreateConnection())
{
    using (IModel channel = conn.CreateModel())
    {
        var consumer = new EventingBasicConsumer(channel);
        channel.BasicConsume(queue1, false, consumer);
        channel.BasicConsume(queue2, false, consumer);
        channel.BasicConsume(queue3, false, consumer);
        consumer.Received += (model, ea) =>
        {
            byte[] message = ea.Body.ToArray();
            Console.WriteLine($"交換機:{ea.Exchange} 路由Key:{ea.RoutingKey} 接收到資訊為:{Encoding.UTF8.GetString(message)}");
            channel.BasicAck(ea.DeliveryTag, false);
        };
        Console.ReadKey();
    }
}

結果:

2、當交換器的型別是Fanout型別,與之連線多個佇列,傳送訊息時,是否所有與之連線的佇列都會收到? 答案是肯定的。

傳送端:

using (IConnection con = conFactory.CreateConnection())//建立連線物件
{
    using (IModel channel = con.CreateModel())//建立連線會話物件
    {
        channel.QueueDeclare(queue1, false, false, false, null);
        channel.QueueDeclare(queue2, false, false, false, null);
        channel.QueueDeclare(queue3, false, false, false, null);

        channel.ExchangeDeclare(exchange2, ExchangeType.Fanout);
        channel.QueueBind(queue1, exchange2, routingKey2);
        channel.QueueBind(queue2, exchange2, routingKey2);
        channel.QueueBind(queue3, exchange2, routingKey2);

        while (true)
        {
            Console.Write("訊息內容:");
            var message = Console.ReadLine();
            byte[] body = Encoding.UTF8.GetBytes(message);
            channel.BasicPublish(exchange2, routingKey2, null, body);
            Console.WriteLine("成功傳送訊息:" + message);
        }
    }

消費端 程式碼不變。

結果:

3、當一個佇列有多個消費者,是否所有的消費者都能接收到訊息? 答案是否定的。會輪詢傳送給監聽的所有消費者

傳送端:程式碼不變

消費端:新增一個消費者

using (IConnection conn = connFactory.CreateConnection())
{
    using (IModel channel = conn.CreateModel())
    {
        var consumer = new EventingBasicConsumer(channel);

        var consumer2=new EventingBasicConsumer(channel);
        channel.BasicConsume(queue1, false, consumer);
        channel.BasicConsume(queue2, false, consumer);
        channel.BasicConsume(queue3, false, consumer);

        channel.BasicConsume(queue1, false, consumer2);
        channel.BasicConsume(queue2, false, consumer2);
        channel.BasicConsume(queue3, false, consumer2);

        consumer.Received += (model, ea) =>
        {
            byte[] message = ea.Body.ToArray();
            Console.WriteLine($"消費者:consumer1  交換機:{ea.Exchange} 路由Key:{ea.RoutingKey} 接收到資訊為:{Encoding.UTF8.GetString(message)}");
            channel.BasicAck(ea.DeliveryTag, false);
        };

        consumer2.Received += (model, ea) =>
        {
            byte[] message = ea.Body.ToArray();
            Console.WriteLine($"消費者:consumer2 交換機:{ea.Exchange} 路由Key:{ea.RoutingKey} 接收到資訊為:{Encoding.UTF8.GetString(message)}");
            channel.BasicAck(ea.DeliveryTag, false);
        };

        Console.ReadKey();
    }
}

結果: