更多的问题

Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件进行分类。

比如RabbitMQ学习笔记(四)Routing中的列子,我们是按照新闻的类型分类的,分为game, sport, music。

如果game下面有ff7,ff8的子分类,sport下面有soccer, basketball的分类。现在我们要求消费者程序接收game下面ff7子类别的所有新闻,sport下面的soccer子类别的所有新闻 ,以及所有的music新闻,单单使用Direct Exchange不能帮助我们解决这个问题。

Topic Exchange

Topic Exchange和Direct Exchange的用法基本一样。

他们的区别是, Topic Exchange在指定routingKey的时候,必须使用一个单词列表,每个单词之间用”.”间隔, 例如game.ff7, sport.soccer, Topic Exchange使用的routingKey的最大长度是256字节。

而且在Topic Exchange的routingKey中可以使用2种通配符

  • * 匹配任何一个单词, 例* 表示所有的游戏新闻,game.ff7, game.ff8可以匹配,但是game.ff7.music就不能匹配,因为只能匹配一个单词。
  • # 匹配零个或多个单词# 表示也表示游戏所有的新闻,game.ff7,game.ff8可以匹配,game.ff7.music也可以匹配。

你甚至可以这样写*.*.rabbit,表示所有3级新闻类别兔子的新闻,zoo.grass.rabbit和zoo.cage.rabbit都可以匹配

修改代码

Send

  1. 使用Topic Exchange
  2. 发送消息需要指定新闻分类 ,命令格式“dotnet run [分类路径] [消息信息]”
static void Main(string[] args)

        {

            var messageType = args[0];

 

            var factory = new ConnectionFactory()

            {

                HostName = "localhost"

            };

 

            using (var connection = factory.CreateConnection())

            {

                using (var channel = connection.CreateModel())

                {

                    channel.ExchangeDeclare("topicExchange", "topic");

 

                    string message = $"{args[0]} news: {args[1]}";

                    var body = Encoding.UTF8.GetBytes(message);

 

                    channel.BasicPublish(exchange: "topicExchange",

                        routingKey: messageType,

                        basicProperties: null,

                        body: body

                    );

 

                    Console.WriteLine("[x] Sent {0}", message);

                }

            }

        }

Receive

  • 使用Topic Exchange
  • 启动程序时,需要设置希望订阅的新闻分类, 命令格式“dotnet run [新闻分类1] [新闻分类2] ….”
static void Main(string[] args)

        {

            var factory = new ConnectionFactory() { HostName = "localhost" };

 

            using (var connection = factory.CreateConnection())

            {

                using (var channel = connection.CreateModel())

                {

                    channel.ExchangeDeclare("topicExchange", "topic");

 

                    var queueName = channel.QueueDeclare().QueueName;

 

                    foreach (var type in args)

                    {

                        channel.QueueBind(queue: queueName, exchange: "topicExchange", routingKey: type);

                    }

 

                    var consumer = new EventingBasicConsumer(channel);

 

                    consumer.Received += (model, ea) =>

                    {

                        var body = ea.Body;

                        var message = Encoding.UTF8.GetString(body);

                        Console.WriteLine("[x] Received {0}", message);

                    };

 

                    channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);

 

                    Console.Read();

                }

            }

        }

最终效果

  1. 启动一个Send程序,2个Receive程序
  2. 一个Receive程序订阅ff7下面的所有新闻(包含ff7下面所有的子类别新闻),soccer下面的所有新闻(包含soccer下面的所有子类别新闻),music下的所有新闻(不包括子类别新闻)
  3. 一个Receive程序订阅ff8下面的所有新闻(包含ff8下面所有的子类别新闻),basketball下面的所有新闻(包含basketball下面的所有子类别新闻)。

RabbitMQ学习笔记(五) Topic的更多相关文章

  1. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  2. rabbitMQ学习笔记(六) topic类型消息。

    上一节中使用了消息路由,消费者可以选择性的接收消息. 但是这样还是不够灵活. 比如某个消费者要订阅娱乐新闻消息 . 包括新浪.网易.腾讯的娱乐新闻.那么消费者就需要绑定三次,分别绑定这三个网站的消息类 ...

  3. rabbitMQ学习笔记(五) 消息路由

    生产者会生产出很多消息 , 但是不同的消费者可能会有不同的需求,只需要接收指定的消息,其他的消息需要被过滤掉. 这时候就可以对消息进行过滤了. 在消费者端设置好需要接收的消息类型. 如果不使用默认的E ...

  4. openresty 学习笔记五:访问RabbitMQ消息队列

    openresty 学习笔记五:访问RabbitMQ消息队列 之前通过比较选择,决定采用RabbitMQ这种消息队列来做中间件,目的舒缓是为了让整个架构的瓶颈环节.这里是做具体实施,用lua访问Rab ...

  5. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  6. 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

    在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...

  7. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  8. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  9. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

随机推荐

  1. IMCASH:2019年区块链不会风平浪静,至少还有10件事值得期待

    当我们在说2019年是值得期待的一年时,我们还是得做到有根有据.那么,2019年在区块链行业都会发生哪些引导行业风向.影响整个行业的事件呢? 今天,白话区块链带着大家顺着时间线梳理一下. 01 第一季 ...

  2. anaconda 命令集合

    0.安装 $ bash ~/Downloads/Anaconda3-5.3.1-MacOSX-x86_64.sh source ~/.bash_profile 1.查看 anaconda 的版本 co ...

  3. python爬取网页内容demo

    #html文本提取 from bs4 import BeautifulSoup html_sample = '\ <html> \ <body> \ <h1 id = & ...

  4. 虚拟机上的Ubuntu 文件系统成为只读模式的解决办法

    虚拟机环境的Linux系统由于是虚拟化虚拟出来的主机环境,因此 经常会出现一些操作系统的问题,今天我遇到了一个Ubuntu操作系统文件系统成了只读模式,无法进行系统的操作,由于出问题的主机是我个人搭建 ...

  5. 使用curl上传图片的方法

    关键:当参数名为"@绝对路径",这时 CURL 會幫你做 multipart/form-data 編碼 实现方法: $params = array( 'file' => '@ ...

  6. hyperopt自动调参

    hyperopt自动调参 在传统机器学习和深度学习领域经常需要调参,调参有些是通过通过对数据和算法的理解进行的,这当然是上上策,但还有相当一部分属于"黑盒" hyperopt可以帮 ...

  7. JS与IOS、Android的交互

    一.JS与Android 放在了assets文件夹下了(注意若使用的是AS这个IDE,assets文件夹应放在src/main目录下) <!DOCTYPE html> <html&g ...

  8. springboot-项目获取resources下文件碰到的问题(classPath下找不到文件和文件名乱码)

    项目是spring-boot + spring-cloud 并使用maven 管理依赖.在springboot+maven项目下怎么读取resources下的文件实现文件下载? 怎么获取resourc ...

  9. Python练手例子(14)

    79.字符串排序. #python3.7 if __name__ == '__main__': str1 = input('Input string:\n') str2 = input('Input ...

  10. [IOT] 自制蓝牙工牌办公室定位系统 (二)—— 基于ESP32的蓝牙信号扫描系统

      前面章节: 自制蓝牙工牌办公室定位系统 (一)-- 阿里物联网平台概览及打通端到云(硬核·干货)   目录: 1.蓝牙广播简介 2.蓝牙扫描简介 3.基于蓝牙广播和蓝牙扫描常见应用 4.ESP32 ...