RabbitMQ的发布订阅模式(Publish/Subscribe)
一、发布/订阅(Publish/Subscribe)模式
发布订阅是我们经常会用到的一种模式,生产者生产消息后,所有订阅者都可以收到。RabbitMQ的发布/订阅模型图如下:

1、该模式下生产者并不是直接操作队列,而是将数据发送给交换机,由交换机将数据发送给与之绑定的队列;
2、该模式必须声明交换机,并且设置模式: channel.ExchangeDeclare(EXCHANGE_NAME, type: ExchangeType.Fanout);
fanout指分发模式(将每一条消息都发送到与交换机绑定的队)。
3、队列必须绑定交换机:channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
二、发布消息
消息生产者向交换机(exchange)发送消息,代码如下:
// 定义交换机名称
static string EXCHANGE_NAME = "ps_exchange_fanout";
public static void PublishMessage()
{
try
{
var conn = RabbitMQHelper.GetConnection();
var channel = conn.CreateModel();
// 定义exchange
channel.ExchangeDeclare(EXCHANGE_NAME, type: ExchangeType.Fanout);
string msg = "hello ps!";
var body = Encoding.UTF8.GetBytes(msg);
channel.BasicPublish(EXCHANGE_NAME, "", null, body);
Console.WriteLine("send msg:" + msg);
channel.Close();
conn.Close();
}
catch (Exception ex)
{
throw ex;
}
}
消息发送成功,截图如下:

三、订阅消息
在这里需要两个消费者,消息发送后,所有的订阅者都可以收到消息;
3.1 消费者1
和轮询分发以及公平分发不同的是,消费者需要将队列绑定到交换机,来订阅消息;实现代码如下:
static string EXCHANGE_NAME = "ps_exchange_fanout";
static string QUEUE_NAME = "ps_queue_sub1";
/// <summary>
/// 订阅消费者1
/// </summary>
static void SubscribeConsumer1()
{
var conn = RabbitMQHelper.GetConnection();
var channel = conn.CreateModel();
// 定义exchange
channel.ExchangeDeclare(EXCHANGE_NAME, type: ExchangeType.Fanout);
// 绑定queue
channel.QueueDeclare(queue: QUEUE_NAME);
channel.QueueBind(QUEUE_NAME, EXCHANGE_NAME, "");
// 定义Consumer
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model,ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body.ToArray());
Console.WriteLine($"SubscribeConsumer1 收到消息: {message},时间:{DateTime.Now}");
};
//启动消费者 设置为手动应答消息
channel.BasicConsume(queue: QUEUE_NAME, autoAck: true, consumer: consumer);
Console.WriteLine("Subscribe Consumer1 消费者已启动");
Console.ReadKey();
channel.Dispose();
conn.Close();
}
3.2 消费者2
消费者2的代码和1的基本相同,大家可以将1的修改一下,就可以使用,在此就不重复贴出了;
3.3 接收消息结果
消费者1接收消息截图:

消费者2接收消息截图:

通过上图,我们可以看到,发布者发布消息后,订阅者1、2均受到了相同的消息,至此功能已经完成;
四、小结
4.1 订阅者代码的主要流程
根据消费者的代码,我们可以提炼流程如下
(1)创建连接
(2)声明exchange
(3)绑定队列到exchange
(4)声明消费者
(5)绑定消费者到channel,监听处理消息
(6)关闭连接
4.2 订阅成功后,我们打开mq的管理地址可以看到,有两个queue绑定到exchange上了:

注意:如果我们的exchange没有消费者订阅,发布的消息将不会被保存到任何队列,直接丢失了;
参考链接:https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html
RabbitMQ的发布订阅模式(Publish/Subscribe)的更多相关文章
- 【译】RabbitMQ:发布-订阅(Publish/Subscribe)
在前一篇教程中,我们创建了一个工作队列,我们假设在工作队列后的每一个任务都只被调度给一个消费者.在这一部分,我们将做一些完全不一样的事情,调度同一条消息给多个消费者,也就是有名的“发布-订阅”模式.为 ...
- 四.RabbitMQ之发布/订阅(Publish/Subscribe)
一.基础知识点 在上述章节中,我们理解的RabbitMQ是基于如下这种模式运作的. 而事实上,这只是我们简单化了的模型的结果,真正的模型应该是这样的. P:Producer 生产者,生产消息,把它放进 ...
- RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)(转载)
RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe) (本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个 ...
- Mina、Netty、Twisted一起学(七):发布/订阅(Publish/Subscribe)
消息传递有很多种方式,请求/响应(Request/Reply)是最常用的.在前面的博文的例子中,很多都是采用请求/响应的方式,当服务器接收到消息后,会立即write回写一条消息到客户端.HTTP协议也 ...
- RabbitMQ入门:发布/订阅(Publish/Subscribe)
在前面的两篇博客中 RabbitMQ入门:Hello RabbitMQ 代码实例 RabbitMQ入门:工作队列(Work Queue) 遇到的实例都是一个消息只发送给一个消费者(工作者),他们的消息 ...
- RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)
(本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向 ...
- RabbitMQ 之 订阅模式 Publish/Subscribe
模型图 我们之前学习的都是一个消息只能被一个消费者消费,那么如果我想发一个消息 能被多个消费者消费,这时候怎么办? 这时候我们就得用到了消息中的发布订阅模型 在前面的教程中,我们创建了一个工作队列,都 ...
- RabbitMQ入门-发布订阅模式
兔子的Publish/Subscribe是这样的: 有个生产者P,X代表交换机,交换机绑定队列,消费者从队列中取得消息.每次有消息,先发到交换机中,然后由交换机负责发送到它已知的队列中. 生产者代码: ...
- 观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 抽象主题(Subject):它把所有观察者对 ...
随机推荐
- Daily Scrum 1/18/2016
Yandong & Zhaoyang: Prepare bug bash slides for Beta release; Dong & Fuchen:Prepare demo for ...
- ajax ★ ★ ★ ★ ★
ajax 1 定义: 是创建交互式应用的网页交互技术 2 特点:无刷新.异步 3 中介数据类型: 1) XML - 可扩展的标记语言 ...
- 详解 普通数组 —— Arrays类 与 浅克隆
我们在C语言中,编一些代码量规模比较大的程序,几乎都会用到 "数组" 或 "链表" ,但是,在本人之前的博文中,却对这两个知识点从未提到过,那么,本人将通过这篇 ...
- SpringBoot集成MyBatis底层原理及简易实现
MyBatis是可以说是目前最主流的Spring持久层框架了,本文主要探讨SpringBoot集成MyBatis的底层原理.完整代码可移步Github. 如何使用MyBatis 一般情况下,我们在Sp ...
- [html][javascript] 关于SVG环形进度条
下面是个例子: <style> .demo2{ transform-origin: center; transform: rotate(-90deg); transition: strok ...
- 44道JavaScript送命题
很久以前看过一个老外写的帖子,JavaScript Puzzlers!,直译就是JavaScript难题,里面列举了100道JavaScript选择题,大部分都是让人摸不着头脑的题目,需要仔细琢磨一番 ...
- 想学习CTF的一定要看这篇,让你学习效率提升80%
在学习CTF过程中你是否遇到这样的情况: 下定决心想要学习CTF,不知道从哪里开始? 找了一堆CTF相关的知识学习,但是知识点太凌乱,没有统一明确的学习路径. 又或者理论学习完,没有相应的实操环境? ...
- es6最 全教程2020年
带手机验证码登陆, 带全套购物车系统 带数据库 前后端分离开发 带定位用户功能 数据库代码为本地制作好了 带支付宝支付系统 带django开发服务器接口教程 地址: https://www.dua ...
- Spring Boot JPA的查询语句
文章目录 准备工作 Containing, Contains, IsContaining 和 Like StartsWith EndsWith 大小写不敏感 Not @Query Spring Boo ...
- Vue tools开发工具报错Cannot read property '__VUE_DEVTOOLS_UID__' of undefined
使用 vue tools 开发工具,不显示调试面板中的组件,点击控制台报错: Cannot read property 'VUE_DEVTOOLS_UID' of undefined 在 main.j ...