NetCore RabbitMQ Topics 通配符模式

十年河東,十年河西,莫欺少年窮

學無止境,精益求精

上一節介紹了RabbitMQ定向模式,本篇介紹 Topics 通配符模式

我的系列博客:

NetCore RabbitMQ ,Routing定向模式

NetCore RabbitMQ 發佈訂閱模式,消息廣播

RabbitMQ的六種工作模式

NetCore RabbitMQ 簡介及兔子生產者、消費者 【簡單模式,work工作模式,競爭消費】

windows環境下,RabbitMQ 安裝教程

kafka、Rabbitmq、EasyNetQ NetCore 源碼下載 僅自己可見

本篇介紹Topics通配符模式

1.5 topic 主題模式(路由模式的一種)

在這裏插入圖片描述

  1. 星號井號代表通配符
  2. 星號1個字符井號代表0個或多個字符
  3. 路由功能添加模糊匹配
  4. 消息產生者產生消息,把消息交給交換機
  5. 交換機根據key的規則模糊匹配到對應的隊列,由隊列的監聽消費者接收消息消費

Topics通配符模式和定向模式類似,都是通過RoutingKey定向到不到的隊列中,不同的是Topics通配符模式只是通配符,有了通配符,就可以做到模糊匹配。

Topics模式中支持兩種通配符

* 代表1個字符

# 代表0個或多個字符

例如

路由Key定義爲 *.Dog.* ,那麼我們發送消息時中間爲Dog且前後均爲一個字符的路由key都可以匹配到該通配符,例如:C.Dog.D 【注意要帶上 . 】

路由Key定義爲 #.Dog ,那麼發送消息時以Dog結尾的路由Key都可以匹配到該通配符,例如 chenwolong.Dog【注意要帶上 . 】

路由Key定義爲 Dog.# ,那麼發送消息時以Dog開頭的路由Key都可以匹配到該通配符 ,例如 Dog.Chenwolong【注意要帶上 . 】

路由Key定義爲 #.#  ,那麼 Dog.Cat,Cat.Dog  . 等都可以匹配

下面由代碼進行說明

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqProducer
{
    class Program
    {
        /// <summary>
        /// 本示例紅色預警爲最高預警級別,藍色預警次之,黃色預警等級最差
        /// 紅色預警隊列中只展示紅色預警消息,
        /// 藍色預警隊列中展示紅色預警和藍色預警 
        /// 黃色預警隊列展示紅、藍、黃三種預警
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
            using (var connection = factory.CreateConnection()) 
            {
                //rabbitMQ 基於信道進行通信,因此,我們需要實例化信道Channel
                using (var channel = connection.CreateModel())
                {
                    //exchange 交換機名稱
                    //type  交換機類型  ExchangeType.Direct【定向模式】  ExchangeType.Fanout【廣播模式】  ExchangeType.Topic【通配符模式】  ExchangeType.Headers 【參數匹配模式】
                    //durable 是否持久化
                    //autoDelete 隊列是否爲臨時隊列
                    //arguments  其他配置 詳見博客:https://www.cnblogs.com/chenwolong/p/RabbitMQ_S.html
                    //void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary<string, object> arguments);
                    //聲明一個交換機  類型 : Direct
                    string Ename = "ExRabbitMQ_Topic";
                    channel.ExchangeDeclare(Ename, ExchangeType.Topic, false, false, null);
                    //聲明廣播的隊列
                    string Qname_Red = "Queue_Red";
                    string Qname_Blue = "Queue_Blue"; 
                    channel.QueueDeclare(Qname_Red, false, false, false, null);
                    channel.QueueDeclare(Qname_Blue, false, false, false, null); 
                    //交換機 隊列 綁定
                    //queue 隊列名稱
                    //exchange  交換機名稱
                    //routingKey  路由規則  
                    //void QueueBind(string queue, string exchange, string routingKey, IDictionary<string, object> arguments);
                    string routingKey_Red = "Red.#"; // 紅色預警
                    string routingKey_Blue = "*.Blue"; // 藍色預警 
                    // 
                    channel.QueueBind(Qname_Red, Ename, routingKey_Red);
                    // 
                    channel.QueueBind(Qname_Blue, Ename, routingKey_Blue);
                 
                    //發送消息
                    for(int i = 0; i < 10 ; i++)
                    {
                        var messages_HotRed = "#號匹配0個或多個字符,我是高溫紅色預警(Red.Hot)"; //傳遞的消息內容
                        var messages_FloodRed = "#號匹配0個或多個字符,我是洪澇紅色預警(Red.Floot)"; //傳遞的消息內容
                        var messages_Blue = "*號匹配一個字符,我是藍色預警(A.Blue)"; //傳遞的消息內容 
                                                                    //exchange 交換機,如果使用默認的交換機,那麼routingKey要和隊列的名稱一致
                                                                    //routingKey:路由  
                                                                    //basicProperties : 用於基礎屬性設置
                        ///BasicPublish(this IModel model, string exchange, string routingKey, IBasicProperties basicProperties, ReadOnlyMemory<byte> body);
                        //注意發送消息時,路由Key的匹配規則
                        channel.BasicPublish(Ename, "Red.Hot", null, Encoding.UTF8.GetBytes(messages_HotRed + "_" + i)); //生產高溫紅色預警消息
                        channel.BasicPublish(Ename, "Red.Flood", null, Encoding.UTF8.GetBytes(messages_FloodRed + "_" + i)); //生產洪澇紅色預警消息
                        channel.BasicPublish(Ename, "A.Blue", null, Encoding.UTF8.GetBytes(messages_Blue + "_" + i)); //生產藍色預警消息
                    }
                }
            }
            Console.Read();
        }
    }
}
View Code

藍色預警消費者端如下:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
                                           //創建連接
            var connection = factory.CreateConnection();
            //創建通道
            var channel = connection.CreateModel();

            //事件基本消費者
            EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                Console.WriteLine($"藍色預警隊列消費者收到消息: {message}");
                //確認該消息已被消費
                channel.BasicAck(ea.DeliveryTag, false); Thread.Sleep(100);
            };
            //啓動消費者 
            string Qname = "Queue_Blue";
            channel.BasicConsume(Qname, false, consumer);
            Console.WriteLine("消費者已啓動");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        } 
    }
}
View Code

紅色預警消費者端如下:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
                                           //創建連接
            var connection = factory.CreateConnection();
            //創建通道
            var channel = connection.CreateModel();

            //事件基本消費者
            EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                Console.WriteLine($"紅色預警隊列消費者收到消息: {message}");
                //確認該消息已被消費
                channel.BasicAck(ea.DeliveryTag, false); Thread.Sleep(100);
            };
            //啓動消費者 
            string Qname = "Queue_Red";
            channel.BasicConsume(Qname, false, consumer);
            Console.WriteLine("消費者已啓動");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        } 
    }
}
View Code

 

上一節定向模式中,需要多次綁定,本節通配符模式可以模糊匹配

 @天才臥龍的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章