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):它把所有观察者对 ...
随机推荐
- sqli-labs通关教程----21~30关
第二十一关 第二十一关我们正常登陆后看到,uname后面变成了一堆字母 这是经过base64编码之后的样子,所以就照葫芦画瓢,将我payload的uname后面的部分转码成base64,这里可以用正常 ...
- mysql datetime类型 按格式在页面输出
mysql datetime类型对应java Date类型 java.util.Date类型会显示时间戳 java.sql.Date 只显示年月日不显示时分秒 只需要重写get方法 就能按格式输出 ...
- JavaScript中的作用域和作用域链(边学边写)[看着别人的博客纯手敲]
作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理.今天这篇文章对JavaScript作用域和作用域链简单的介绍,希望能帮 ...
- java算法-二分法查找实现
什么是二分法查找 首先,使用二分法查找的前提是:被查找的数组已排好序 具体实现: 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别 ...
- jQuery(*****)
参考1 参考2 1. jQuery 1. 选择器 $("") 1. 基本选择器 1. ID --> $("#d1") 2. 标签名 --> $(&q ...
- ES6让字符串String增加了哪些好玩的特性呢?
确实因为现在天气变热了,所以一天天的这么写我也很累.所以如果阅读的时候有什么错误还请大家指出来,不好意思.学习永无止境. OK,今天继续讲解ES6系列知识 学过上一节的解构赋值就知道,ES6确实给我们 ...
- Mac home 目录下创建文件夹
example:sudo vim /etc/auto_master before: # Automounter master map +auto_master # Use directory serv ...
- Vue3.0新版API之composition-api入坑指南
关于VUE3.0 由于vue3.0语法跟vue2.x的语法几乎是完全兼容的,本文主要介绍了如何使用composition-api,主要分以下几个方面来讲 使用vite体验vue3.0 composit ...
- 01-复杂度2 Maximum Subsequence Sum
01-复杂度2 Maximum Subsequence Sum (25分) 时间限制:200ms 内存限制:64MB 代码长度限制:16kB 判题程序:系统默认 作者:陈越 单位:浙江大学 htt ...
- 批量将制定文件夹下的全部Excel文件导入微软SQL数据库
以下代码将c:\cs\文件夹下的全部Excle中数据导入到SQL数据库 declare @query vARCHAR(1000) declare @max1 int declare @count1 i ...