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