fanout 多播
在之前都是使用direct直連類型的交換機,通過routingkey來決定把消息推到哪個queue中。
而fanout則是把拿到消息推到與之綁定的所有queue中。
分析業務,怎樣的場景需要它呢?某個用戶注冊了網站的用戶,一般我們需要發送短信和郵件通知,莫非要在同一個consumer中把這兩件事都做了?這不符合單一職責,可是發送的消息是一樣的,只是方式不一樣。要使用兩種routingkey都發送一次?這顯然也不是我們想要的。所以fanout出現了
fanout類型的exchange會把消息推到所有的queue中,所以不需要指定routingkey,指定了也沒用!
下面通過代碼來看
這里有兩種需求,發短信與發郵件
//創建返回一個新的頻道 using (var channel = RabbitMqHelper.GetConnection().CreateModel()) { //發布一個消息 var msg = Encoding.UTF8.GetBytes($"二狗子"); //不需要指定routingkey,指定了也沒用.因為交換機是fanout類型 channel.BasicPublish("fanoutExchange", routingKey: string.Empty, basicProperties: null, body: msg); Console.Write("發布成功!"); } Console.ReadKey();
這里是consumer部分的代碼
bool flag = true; string pattern = ""; while (flag) { Console.WriteLine("請選擇Ccnsumer模式 1(發短信)/2(發郵件)"); pattern = Console.ReadLine(); if (pattern == "1" || pattern == "2") flag = false; else Console.Write("請做出正確的選擇"); } using (var channel = RabbitMqHelper.GetConnection().CreateModel()) { //聲明交換機 Fanout模式 channel.ExchangeDeclare("fanoutExchange", ExchangeType.Fanout, true, false, null); //根據聲明使用的隊列 var queueName = pattern == "1" ? "sms" : "emai"; channel.QueueDeclare(queueName, true, false, false, null); //進行綁定 channel.QueueBind(queueName, "fanoutExchange", string.Empty, null); //創建consumbers var consumer = new EventingBasicConsumer(channel); consumer.Received += (sender, e) => { var msg = Encoding.UTF8.GetString(e.Body); var action = (pattern == "1" ? "發短信" : "發郵件"); Console.WriteLine($"給{msg}{action}"); }; //進行消費 channel.BasicConsume(queueName, true, consumer); Console.ReadKey(); }
下面把程序運行起來,不同的consumer進行了不同的消費