消息的订阅和发布是使用消息队列的常用场景。在上一篇文章中,虽然有多个消费者,但是一个消息只会有一个消费者来处理。而订阅和发布则是每个订阅该消息的消费者都会收到这个消息。RabbitMQ的路由机制让我们实现这个功能轻而易举。

要了解RabbitMQ的路由机制,exchange是一个关键。exchange可以叫做交换机,也似乎可以叫做路由器,反正它是用来选择路由的。前文说到,RabbitMQ的核心思想就是消息的发布者不是直接把消息发送到目标队列中的,事实上,通常它并不知道消息要发到哪个队列中,它只知道把消息队列发送到exchange中。exchange一边接收发送者发过来的消息,而另一边则把消息发送到目标队列中去。exchange一定知道哪些队列需要接收这个消息,是加到一个队列里还是加到好几个队列里,还是直接扔掉。下图中的X就是exchange。

RabbitMQ的exchange有一些类型,这些类型决定了exchange的行为。分别是 direct, topic, headers 和 fanout四种类型。在这一篇文章中介绍的最简单的发送和接收例子中使用的如下代码中

//指定发送的路由,通过默认的exchange直接发送到指定的队列中。
channel.BasicPublish("", "esbtest.rmq.consoleserver", null, bytes);

第一个参数我们输入了空字符串来代表一个exchange。空字符串的exchange在RabbitMQ中时默认的exchange,类型是direct。在这个例子中它会直接将消息发送到第二个参数route_key定义的同名的队列中。

而我们这篇介绍的订阅和发布是用了fanout这个类型。由于默认类型是direct的,所以需要使用fanout就需要额外定义。如下代码就是定义了一个名字叫publish的fanout类型的exchange。

channel.ExchangeDeclare("publish", "fanout");

这种exchange有分发的意思。那分发到哪些队列中呢?因为发布者不需要知道,所以这段代码页就在订阅者那边来实现。来看订阅者得代码片段:

using (IConnection connection = factory.CreateConnection())
            {
                using (IModel channel = connection.CreateModel())
                {
                    channel.ExchangeDeclare("publish", "fanout");
                    //随机创建一个队列
                    string queue_name = channel.QueueDeclare("subscriber1", true, false, false, null);
                    //绑定到名字叫publish的exchange上
                    channel.QueueBind(queue_name, "publish", "");
                    //定义这个队列的消费者
                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    channel.BasicConsume(queue_name, true, consumer);
 
                    while (true)
                    {
                        BasicDeliverEventArgs ea =
                            (BasicDeliverEventArgs)consumer.Queue.Dequeue();
 
                        byte[] bytes = ea.Body;
 
                        XmlSerializer xs = new XmlSerializer(typeof(RequestMessage));
                        using (MemoryStream ms = new MemoryStream(bytes))
                        {
                            RequestMessage message = (RequestMessage)xs.Deserialize(ms);
                            Console.WriteLine("Receive a Message, Id:" + message.MessageId + " Message:" + message.Message);
                        }
                    }
                }
            }

同样先定义一个fanout的exchange。对于为什么要在发布者和订阅者都要定义同名的exchange,我的理解是如果没有定义的一方先启动的话则会报错说找不到那个exchange。我测试过如果有定义的先启动,没定义的后启动也是没有问题的。

因为每个订阅者都需要一个队列来存放发给自己的消息,所以需要创建一个队列。通过QueueBind来和exchange关联了。所有发送给名字为publish的exchange的消息,都会被它分发给所有与之绑定的队列中,这样,每个对应的消费者都会收到一个副本。

在浏览器的管理界面上我们可以看见,RabbitMQ为每一个消费者(订阅者)创建了一个队列,而没有为发送者创建队列。

从这里下载示例代码

转载于:https://www.cnblogs.com/haoxinyue/archive/2012/09/27/2705660.html

.Net下RabbitMQ的使用(4) -- 订阅和发布相关推荐

  1. ESP32的MQTT AT固件烧录+STM32以ESP32的MQTT AT固件的AT指令连接EMQX下mqtt服务器实现消息订阅和发布

    目录 写在前面 三种方案(利用ESP32连接EMQX下的MQTT) 步骤 ESP32烧录固件并AT指令进行测试. 下载固件 烧录工具下载 烧录固件(选择ESP32) 关于AT 指令与MQTT服务器断开 ...

  2. Windows下RabbitMQ安装及注意事项

    Windows下RabbitMQ安装及注意事项 简介 背景 1.      RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现. Rabbit ...

  3. Windows下RabbitMQ安装,部署,配置

    安装部署 1.当前环境以及参考资料出处 部署环境:windows server 2008 r2 enterprise 官方安装部署文档:http://www.rabbitmq.com/install- ...

  4. :Windows下RabbitMQ安装及入门

    1.Windows下安装RabbitMQ需要以下几个步骤 (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang. ...

  5. rabbitmq怎么停止_Windows环境下RabbitMQ的启动和停止命令

    Windows环境下RabbitMQ的启动和停止命令 原创lockie_zou 最后发布于2018-05-24 15:34:21 阅读数 36514  收藏 展开 首先windows下安装好了erla ...

  6. rabbitmq 查看消费者_(Windows环境下)RabbitMQ系列(一)安装以及入门使用

    一.RabbitMQ介绍 RabbitMQ是一个消息代理:它接受和转发消息.你可以把它想象成一个邮局.在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员. RabbitMQ和邮局的主要区别在于它不 ...

  7. Docker下RabbitMQ四部曲之四:高可用实战

    本章是<Docker下RabbitMQ四部曲>系列的终篇,今天的我们一起来体验Rabbit'MQ集群的高可用能力,看看RabbitMQ集群中的部分节点宕机时,是否还能生产和消费消息: 前文 ...

  8. Docker下RabbitMQ四部曲之一:极速体验(单机和集群)

    从本章开始,我们一起在Docker环境实战RabbitMQ环境部署和对应的Java开发,当前是<Docker下RabbitMQ四部曲>系列的第一篇,整个系列由以下四篇文章组成: 第一篇,即 ...

  9. 【RabbitMQ】回顾下RabbitMQ知识点,还记得哪些?

    回顾下RabbitMQ知识点,还记得哪些? 什么是RabbitMQ? 为什么要选择RabbitMQ,不选其他MQ? 使用MQ可以解决那些问题? RabbitMQ如何保证消息的有序性? 如何防止MQ消息 ...

  10. 【订阅与发布机制版】spring boot高性能实现二维码扫码登录(下)

    点击上方[JAVA乐园],选择"置顶公众号",有内涵有价值的文章第一时间送达! 作者: 刘冬 来源:https://www.cnblogs.com/GoodHelper/p/865 ...

最新文章

  1. (转)Unity Assets目录下的特殊文件夹名称(作用和是否会被打包到build中)
  2. leetcode 10、Regular Expression Matching
  3. c modern approach‘s forteenth chapter‘s study
  4. MySQL深潜|剖析Performance Schema内存管理
  5. 2020idea插件怎么同步_没有用过这些插件,别说你在用vscode
  6. 一个简单的主机管理模拟程序
  7. MySQL--存储引擎篇
  8. linux .deb后缀文件,tar.gz和bin,以及rpm,deb等linux后缀的文件的区别
  9. 首都师范大学计算机技术复试分数线,2020年首都师范大学计算机应用技术考研分析...
  10. 松下PLC连接海创-IIoT平台案例
  11. 图像处理 之 扫描全能王代替品
  12. 大气金属片头LOGO扫光动画PR模板MOGRT
  13. 利用注册表更改文件默认打开方式及图标
  14. 前端网站开发页面重定向的几种方法
  15. goahead(嵌入式) webservice (3.3.0)运行goforms
  16. LightSwitch 社区内容汇总 – 2012年9月
  17. nodejs服务使用pm2启动多个进程和进程守护,以及使用pm2-logrotate-ext分割日志
  18. SQL报错Every derived table must have its own alias
  19. Ext入门的第一个程序(1)
  20. 大数据毕业设计 基于时间序列的股票预测与分析系统 - 大数据分析

热门文章

  1. cv如何连接mysql_Naicvat操作数据库的基本操作
  2. oracle11g怎样进行闪回,模拟Oracle11g下用Flashback Data Archive进行恢复的若干场景
  3. CV进阶 -- 目标检测原理及代码实现、YOLO源码解读学习
  4. grasshopper for rhino 6下载_漫谈算法设计与脚本语言(grasshopper, python)
  5. 移动应用市场统计分析
  6. RF中的 click element
  7. 站在巨人的肩膀上学习Android开发
  8. 【电源】开关电源、线性稳压电源
  9. Lazy Load Plugin for jQuery延迟加载测试成功
  10. 高职院校计算机实验室管理的对策与思考