RabbitMQ learning subscription mode (taking C# code as an example)

Posted by cvjacques on Sun, 02 Jan 2022 07:13:09 +0100

Subscription mode (Publish/Subscribe)

When a message is sent to many consumers at one time, the message sent by one producer will be obtained by multiple consumers, that is, the message will be broadcast to all consumers.

Application scenario: after updating the commodity inventory, you need to notify multiple caches and databases. The structure here should be:

  • A fan out switch fans out two message queues: cache message queue and database message queue
  • A cache message queue corresponds to multiple cache consumers
  • A database message queue corresponds to multiple database consumers

In the subscription model, an Exchange role is added, and the process changes slightly:

Exchange: Exchange (X). On the one hand, it receives messages sent by producers. On the other hand, it knows how to process messages, such as submitting to a special queue, submitting all queues, or discarding messages. How to operate depends on the type of exchange. There are three common types of exchange

Fanout: broadcast and deliver messages to all queues bound to the switch. This type is used for subscription mode

Direct: directional, which sends messages to queues that match the specified routing key. This type is used in routing mode

Topic: wildcard character. The message is sent to the queue matching the routing pattern. This type is used in the topic mode

Exchange is only responsible for forwarding messages and does not have the ability to store messages. Therefore, if there is no queue bound to exchange or no queue that meets the routing rules, messages will be lost

Demo , simulate Baidu and Sina to subscribe to the weather information released by the Meteorological Bureau

 

1.RabbitMQ.Common class library code

  (1)RabbitConstant.cs code

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace RabbitMQ.Common
 6 {
 7     public class RabbitConstant
 8     {
 9         public const string QUEUE_HELLO_WORLD = "helloworld.queue";
10         public const string QUEUE_SMS = "sms.queue";
11         public const string EXCHANGE_WEATHER = "weather.exchange";
12         public const string QUEUE_BAIDU = "baidu.queue";
13         public const string QUEUE_SINA= "sina.queue";
14         public const string EXCHANGE_WEATHER_ROUTING = "weather.routing.exchange";
15         public const string EXCHANGE_WEATHER_TOPIC = "weather.topic.exchange";
16     }
17 }

 (2)RabbitUtils.cs code

 1 using System;
 2 using RabbitMQ.Client;
 3 
 4 namespace RabbitMQ.Common
 5 {
 6     public class RabbitUtils
 7     {
 8         public static ConnectionFactory GetConnection()
 9         {
10             var factory = new ConnectionFactory();
11             factory.HostName = "127.0.0.1";
12             factory.Port = 5672;//Is the port number of the server, which is different from the port number 15672 on the page
13             factory.UserName = "guest";
14             factory.Password = "guest";
15             //factory.VirtualHost = "/";
16             return factory;
17         }
18     }
19 }

2. RabbitMQ.Producer console project code

(1)WeatherFanout.cs code

 1 using System;
 2 using System.Text;
 3 using RabbitMQ.Client;
 4 using RabbitMQ.Common;
 5 
 6 namespace RabbitMQ.Producer.Producer
 7 {
 8     public class WeatherFanout
 9     {
10         public static void SendWeatherInfo()
11         {
12             using (var connection = RabbitUtils.GetConnection().CreateConnection())
13             {
14                 using (var channel = connection.CreateModel())
15                 {
16                         string message = "Minus 10 degrees";
17                         var body = Encoding.UTF8.GetBytes(message);
18               
19                         channel.BasicPublish(exchange: RabbitConstant.EXCHANGE_WEATHER,
20                                              routingKey: "",
21                                              basicProperties: null,
22                                              body: body);
23                     Console.WriteLine("Weather information sent successfully");
24                     Console.WriteLine("Press [Enter] to exit");
25                     Console.ReadLine();
26                 }
27             }
28         }
29     }
30 }

(2)Program.cs code

 1 using RabbitMQ.Producer.Producer;
 2 using System;
 3 
 4 namespace RabbitMQ.Producer
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             WeatherFanout.SendWeatherInfo();
11         }
12     }
13 }

3.RabbitMQ.Consumer01 console project code

(1)WeatherFanout.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using RabbitMQ.Common;
 5 using RabbitMQ.Client;
 6 using RabbitMQ.Client.Events;
 7 
 8 namespace RabbitMQ.Consumer01.Consumer
 9 {
10     public  class WeatherFanout
11     {
12         public static void ReceiveWeatherInfo()
13         {
14             using (var connection = RabbitUtils.GetConnection().CreateConnection())
15             {
16                 using (var channel = connection.CreateModel())
17                 {
18                     channel.ExchangeDeclare(RabbitConstant.EXCHANGE_WEATHER, ExchangeType.Fanout);
19                     channel.QueueDeclare(RabbitConstant.QUEUE_BAIDU, true, false, false, null);
20                     /*
21                      * QueueBind Used to bind queues to switches
22                      * queue:Queue name
23                      * exchange:Switch name
24                      * routingKey: Routing key
25                      */
26                     channel.QueueBind(queue: RabbitConstant.QUEUE_BAIDU,
27                                       exchange:RabbitConstant.EXCHANGE_WEATHER,
28                                       routingKey:"");
29                     channel.BasicQos(0, 1, false);
30                     var consumer = new EventingBasicConsumer(channel);
31 
32                     consumer.Received += (model, ea) =>
33                     {
34                         var message = Encoding.UTF8.GetString(ea.Body.ToArray());
35                         Console.WriteLine($"Meteorological information received by Baidu:{message}");
36                         channel.BasicAck(ea.DeliveryTag, false);
37                     };
38                     channel.BasicConsume(queue: RabbitConstant.QUEUE_BAIDU,
39                                  autoAck: false,
40                                  consumer: consumer);
41                     Console.WriteLine(" Press [enter] to exit.");
42                     Console.ReadLine();
43                 }
44             }
45         }
46     }
47 }

(2)Program.cs code

 1 using RabbitMQ.Consumer01.Consumer;
 2 using System;
 3 
 4 namespace RabbitMQ.Consumer01
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             WeatherFanout.ReceiveWeatherInfo();
11         }
12     }
13 }

4.RabbitMQ.Consumer02 console project code

(1)WeatherFanout.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using RabbitMQ.Common;
 5 using RabbitMQ.Client;
 6 using RabbitMQ.Client.Events;
 7 
 8 namespace RabbitMQ.Consumer02.Consumer
 9 {
10     public class WeatherFanout
11     {
12         public static void ReceiveWeatherInfo()
13         {
14             using (var connection = RabbitUtils.GetConnection().CreateConnection())
15             {
16                 using (var channel = connection.CreateModel())
17                 {
18                     channel.ExchangeDeclare(RabbitConstant.EXCHANGE_WEATHER, ExchangeType.Fanout);
19                     channel.QueueDeclare(RabbitConstant.QUEUE_SINA, true, false, false, null);
20                     /*
21                      * QueueBind Used to bind queues to switches
22                      * queue:Queue name
23                      * exchange:Switch name
24                      * routingKey: Routing key
25                      */
26                     channel.QueueBind(queue: RabbitConstant.QUEUE_SINA,
27                                       exchange: RabbitConstant.EXCHANGE_WEATHER,
28                                       routingKey: "");
29                     channel.BasicQos(0, 1, false);
30                     var consumer = new EventingBasicConsumer(channel);
31 
32                     consumer.Received += (model, ea) =>
33                     {
34                         var message = Encoding.UTF8.GetString(ea.Body.ToArray());
35                         Console.WriteLine($"Meteorological information received by Sina:{message}");
36                         channel.BasicAck(ea.DeliveryTag, false);
37                     };
38                     channel.BasicConsume(queue: RabbitConstant.QUEUE_SINA,
39                                  autoAck: false,
40                                  consumer: consumer);
41                     Console.WriteLine(" Press [enter] to exit.");
42                     Console.ReadLine();
43                 }
44             }
45         }
46     }
47 }

(2)Program.cs code

using RabbitMQ.Consumer02.Consumer;
using System;

namespace RabbitMQ.Consumer02
{
    class Program
    {
        static void Main(string[] args)
        {
            WeatherFanout.ReceiveWeatherInfo();
        }
    }
}

5. Execute and run with powershell

 

 

 

 

 

 

 

 

 

 

Reference connection: https://mp.weixin.qq.com/s/QG3uXhhpkE_Uo6Me15mxdg  

                  https://www.bilibili.com/video/BV1GU4y1w7Yq?p=8

 

Topics: C# RabbitMQ