RabbitMQ消息队列(九)-通过Headers模式分发消息(.Net Core版)
Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式。是使用Headers来匹配的。Headers是一个键值对,可以定义成Hashtable。发送者在发送的时候定义一些键值对,接收者也可以再绑定时候传入一些键值对,两者匹配的话,则对应的队列就可以收到消息。
匹配有两种方式all和any。这两种方式是在接收端必须要用键值”x-mactch”来定义。all代表定义的多个键值对都要满足,any代表只要满足一个就可以。fanout,direct,topic exchange的routingKey都需要要字符串形式的,而headers exchange则没有这个要求,因为键值对的值可以是任何类型。
那在.Net Core中怎么应用呢?
headers也是一种交换机类型,但是在rabbitmq官网中的教程中并没有说到。资料也很少,但是找一找总会有的。
headers与direct的模式不同,不是使用routingkey去做绑定。而是通过消息headers的键值对匹配
发布者 -- > headersexchange --> (user: “小明 ”) binding --> queue
也就是说 user: 小明 替代了之前的routingkey。在做绑定的时候有两种匹配方式供选择。x-match (all/any)
意思就是键值对中所有的项都要匹配与只要有一个匹配就可以。下面就可以动手写代码了
新建HeadersProduct用来发布新消息:
using System;
using System.Collections.Generic;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events; namespace HeadersProduct
{
class Program
{
static void Main(string[] args)
{
String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "192.168.63.129";
factory.Port = ;
factory.VirtualHost = "/wyt";
factory.UserName = "wyt";
factory.Password = "wyt"; using (IConnection connection=factory.CreateConnection())
{
using (IModel channel=connection.CreateModel())
{
channel.ExchangeDeclare(exchange: exchangeName, type: "headers", durable: true, autoDelete: false, arguments: null); IBasicProperties properties = channel.CreateBasicProperties();
properties.Headers = new Dictionary<String, Object>()
{
{"user","wyt" },
{"password","wyt"}
}; Byte[] body = Encoding.UTF8.GetBytes("Hello World"); channel.BasicPublish(exchange: exchangeName, routingKey: String.Empty, basicProperties: properties, body: body);
}
} Console.Write("发布成功!"); Console.ReadKey();
}
}
}
新建HeadersConsumerA来以正确的headers接收消息:
using System;
using System.Collections.Generic;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events; namespace HeadersConsumerA
{
class Program
{
static void Main(string[] args)
{ String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "192.168.63.129";
factory.Port = ;
factory.VirtualHost = "/wyt";
factory.UserName = "wyt";
factory.Password = "wyt"; bool flag = true;
string pattern = "";
while (flag)
{
Console.WriteLine("请选择headers匹配模式 1(any)/2(all)");
pattern = Console.ReadLine();
if (pattern == "" || pattern == "")
flag = false;
else
Console.Write("请做出正确的选择");
}
//根据声明使用的队列
var headersType = pattern == "" ? "any" : "all"; using (IConnection connection = factory.CreateConnection())
{
using (IModel channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Headers, durable: true, autoDelete: false, arguments: null); String queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: new Dictionary<String, Object>
{
{"x-math",headersType },
{"user","wyt" },
{"password","wyt" }
}); EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var msg = Encoding.UTF8.GetString(ea.Body); Console.WriteLine($"{msg}");
}; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.ReadKey(); }
}
}
}
}
新建HeadersConsumerB来以错误的headers接收消息:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text; namespace HeadersConsumerB
{
class Program
{
static void Main(string[] args)
{
String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "192.168.63.129";
factory.Port = ;
factory.VirtualHost = "/wyt";
factory.UserName = "wyt";
factory.Password = "wyt"; bool flag = true;
string pattern = "";
while (flag)
{
Console.WriteLine("请选择headers匹配模式 1(any)/2(all)");
pattern = Console.ReadLine();
if (pattern == "" || pattern == "")
flag = false;
else
Console.Write("请做出正确的选择");
}
//根据声明使用的队列
var headersType = pattern == "" ? "any" : "all"; using (IConnection connection = factory.CreateConnection())
{
using (IModel channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Headers, durable: true, autoDelete: false, arguments: null); String queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: new Dictionary<String, Object>
{
{"x-math",headersType },
{"user","xxx" },
{"password","xxx" }
}); EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var msg = Encoding.UTF8.GetString(ea.Body); Console.WriteLine($"{msg}");
}; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.ReadKey(); }
} }
}
}
运行结果

一个可以接收到消息,另一个由于headers是不匹配的,所有接收不到消息
RabbitMQ消息队列(九)-通过Headers模式分发消息(.Net Core版)的更多相关文章
- (八)RabbitMQ消息队列-通过Topic主题模式分发消息
原文:(八)RabbitMQ消息队列-通过Topic主题模式分发消息 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过 ...
- (九)RabbitMQ消息队列-通过Headers模式分发消息
原文:(九)RabbitMQ消息队列-通过Headers模式分发消息 Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式.是使用H ...
- (转)RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)
上篇文章中,我们把每个Message都是deliver到某个Consumer.在这篇文章中,我们将会将同一个Message deliver到多个Consumer中.这个模式也被成为 "pub ...
- RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)
上篇文章中,我们把每个Message都是deliver到某个Consumer.在这篇文章中,我们将会将同一个Message deliver到多个Consumer中.这个模式也被成为 "pub ...
- RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)[转]
上篇文章中,我们把每个Message都是deliver(提供)到某个Consumer.在这篇文章中,我们将会将同一个Message deliver(提供)到多个Consumer中.这个模式也被成为 & ...
- 使用jedis实现Redis消息队列(MQ)的发布(publish)和消息监听(subscribe)
前言: 本文基于jedis 2.9.0.jar.commons-pool2-2.4.2.jar以及json-20160810.jar 其中jedis连接池需要依赖commons-pool2包,json ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列4-复杂对象消息是否需要支持序列化和消息持久化
在上一篇中,我们介绍了消息的顺序收发保证: Azure Messaging-ServiceBus Messaging消息队列技术系列3-消息顺序保证 在本文中我们主要介绍下复杂对象消息是否需要支持序列 ...
- 【消息队列】kafka是如何保证消息不被重复消费的
一.kafka自带的消费机制 kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offs ...
- 获取和设置消息队列的属性msgctl,删除消息队列
消息队列的属性保存在系统维护的数据结构msqid_ds中,用户可以通过函数msgctl获取或设置消息队列的属性. int msgctl(int msqid, int cmd, struct msqid ...
随机推荐
- 1064 Financial Management
http://acm.hdu.edu.cn/showproblem.php?pid=1064 思路:看懂英文就很简单,就是12个数相加求平均数就ok了. 扩展: C++ 标准输入输出流的控制符 #in ...
- win10系统盘分多大合适?
WIN10系统盘分多大合适,想必许多网友在装系统的时候都犹豫不觉吧,不过现在的硬盘基本上都是512G 1T的机械硬盘,固态硬盘基本都是128G以上,256G几乎成为标配,所以WIN10系统盘空间还是足 ...
- [CF893F] Subtree Minimum Query
Description: 给定一棵树,每次询问某点子树中到其不超过k的所有点的最小点权 强制在线 Hint: \(n,m\le 10^5\) Solution: 看到题目第一反应是以深度为下标,dfs ...
- sudo命令详解
语法 sudo(选项)(参数) 选项 选项 说明 -b 在后台执行指令: -h 显示帮助: -H 将HOME环境变量设为新身份的HOME环境变量: -k 结束密码的有效期限,也就是下次再执行sudo时 ...
- 【尺取法】Jurisdiction Disenchantment
[尺取法]Jurisdiction Disenchantment PROBLEM 时间限制: 1 Sec 内存限制: 128 MB 题目描述 The Super League of Paragons ...
- CSS-默认padding 和 margin
一.h1~h6标签:有默认margin(top,bottom且相同)值,没有默认padding值. 在chrome中:16,15,14,16,17,19; 在firefox中:16,15,14,16, ...
- 自己封装element-ui树组件的过滤
前言:vue开发项目时用到了element-ui的树组件,但是发现一执行过滤事件,树就全部都展开了,为了解决这个问题,只能自己先过滤数剧,再赋值给树组件的data,就避免了一上来全部展开的尴尬. 一. ...
- SpringMvc 中的实用工具类介绍(包括 ResponseEntity、 RestTemplate、WebUtils 等)
此部分内容将包含 ResponseEntity. RestTemplate.WebUtils 等 1. ResponseEntity ① Sprring Mvc 中作为方法的返回值使用法 @Reque ...
- mui项目实时更新
var wgtVer=null; function plusReady(){ // ...... // 获取本地应用资源版本号 plus.runtime.getProperty(plus.runtim ...
- C# WPF 使用委托修改UI控件
近段时间在自学WPF,是一个完全不懂WPF的菜鸟,对于在线程中修改UI控件使用委托做一个记录,给自已以后查询也给需要的参考: 界面只放一个RichTextBox,在窗体启动时开起两个线程,调用两个函数 ...