【c#】RabbitMQ学习文档(五)Topic(主题。通配符模式)
(本实例都是使用的Net的客户端,使用C#编写),说明,中文方括号【】表示名词。
在上一个教程中,我们改进了我们的日志记录系统。 没有使用只能够进行虚拟广播的【Fanout】交换机,而是使用了【Direct】类型的交换机,这样做就可以让我们有可能选择性地接收日志。
虽然使用【Direct】类型的【消息交换机】改进了我们的系统,但它仍然有限制 - 它不能基于多个标准进行路由选择。
在我们的日志记录系统中,我们可能不仅要根据严重性订阅日志,还可以基于发出日志的源进行订阅。 您可能会从syslog unix工具中了解这一概念,该工具根据严重性(info/warn/crit...)和设施(auth / cron / kern ...)路由日志。
这将给我们很大的灵活性 - 我们可能既想监听来自“cron”的重要错误,也可以监听“kern”的所有日志。
要在我们的日志记录系统中实现,我们需要了解一个更为复杂的topic类型的【消息交换机】。
1、Topic类型的【消息交换机】
发送到【Topic】类型【消息交换机】的消息不能有任意的routing_key - 它必须是由点分隔的单词列表。 这些词可以是任何东西,但通常它们指定与消息相关联的一些功能。 几个有效的路由关键字示例:“stock.usd.nyse”,“nyse.vmw”,“quick.orange.rabbit”。 路由关键字中可以有任意多的单词,最多可达255个字节。
绑定键也必须是相同的形式。【Topic】类型的【消息交换机】背后的逻辑类似于【Direct】类型的【消息交换机】 - 使用特定【路由键】发送的消息将被传递到与匹配的【绑定键】绑定的所有队列。 但是,【绑定键】有两个重要的特殊情况:
*(星)可以替代一个字。
#(井号)可以替换零个或多个单词。
在一个例子中最简单的解释一下:

在这个例子中,我们将发送所有描述动物的消息。消息将使用由三个字(两个点)组成的【路由键】发送。【路由键】中的第一个字将描述速度,第二个颜色和第三个种类:“<speed>.<color>.<species>”。
我们创建了三个绑定:Q1绑定键“*.orange.*”和Q2是“*.*.rabbit”和“lazy.#”绑定。
这些【绑定键】所要表达意思可以总结为:
Q1对所有的橙色动物感兴趣。
Q2想听听有关兔子的一切,以及关于lazy动物的一切。
将【路由键】设置为“quick.orange.rabbit”的消息将传递给两个队列。消息“lazy.orange.elephant”也会发送他们那两个队列。另一方面,“quick.orange.fox”只会发送到第一个队列,而“lazy.brown.fox”只能发送到第二个队列。 “lazy.pink.rabbit”将被传递到第二个队列只有一次,即使它匹配两个绑定。 “quick.brown.fox”不匹配任何绑定,所以它将被丢弃。
如果我们违反约定并发送一个或四个字的消息,如“orange”或“quick.orange.male.rabbit”,会发生什么?那么这些消息将不会匹配任何绑定,并将丢失。
另一方面,“lazy.orange.male.rabbit”即使它有四个字,将匹配上一个绑定,并将被传递到第二个队列。
说明:【Topic】类型的【消息交换机】
此类型的【消息交换机】是强大的,可以像其他【消息交换机】一样行事。
当队列用“#”(哈希)【绑定键】绑定时,它将接收所有消息,而不管【路由键】,就像使用【Fanout】类型的【消息交换机】。
当特殊字符“*”(星号)和“#”(哈希)不用于绑定时,【Topic】类型的【消息交换机】将表现得像一个使用【Direct】类型的【消息交换机】。
2、代码整合
我们将在我们的日志记录系统中使用【Topic】类型【消息交换机】。 我们将从一个工作假设开始,日志的【路由键】将有两个单词组成:“<facility>.<severity>”。
代码与上一个教程几乎相同。
EmitLogTopic.cs的代码:

using System;
using System.Linq;
using RabbitMQ.Client;
using System.Text; class EmitLogTopic
{
public static void Main(string[] args)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using(var connection = factory.CreateConnection())
using(var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: "topic_logs",
type: "topic"); var routingKey = (args.Length > ) ? args[] : "anonymous.info";
var message = (args.Length > )
? string.Join(" ", args.Skip( ).ToArray())
: "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "topic_logs",
routingKey: routingKey,
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent '{0}':'{1}'", routingKey, message);
}
}
}

ReceiveLogsTopic.cs的代码:

using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text; class ReceiveLogsTopic
{
public static void Main(string[] args)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using(var connection = factory.CreateConnection())
using(var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
var queueName = channel.QueueDeclare().QueueName; if(args.Length < )
{
Console.Error.WriteLine("Usage: {0} [binding_key...]",
Environment.GetCommandLineArgs()[]);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
Environment.ExitCode = ;
return;
} foreach(var bindingKey in args)
{
channel.QueueBind(queue: queueName,
exchange: "topic_logs",
routingKey: bindingKey);
} Console.WriteLine(" [*] Waiting for messages. To exit press CTRL+C"); var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
var routingKey = ea.RoutingKey;
Console.WriteLine(" [x] Received '{0}':'{1}'",
routingKey,
message);
};
channel.BasicConsume(queue: queueName,
noAck: true,
consumer: consumer); Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}

3、运行以下示例:
收到所有的日志:
cd ReceiveLogsTopic
dotnet run“#”
从设备“kern”接收所有日志:
cd ReceiveLogsTopic
dotnet run “kern.*”
或者如果您只想听到关于“critical”日志的信息:
ReceiveLogsTopic.exe“* .critical”
您可以创建多个绑定:
cd ReceiveLogsTopic
dotnet run“kern.*”“*.critical”
并使用【路由键】“kern.critical”类型发出日志:
cd emitLogTopic
dotnet run“kern.critical”“A critial kernel error”
写这些程序很有趣。 请注意,代码不会对【路由键】或【绑定键】做任何假设,您可能希望使用两个以上的【路由键】参数进行操作。
今天就到此为止了,如果英文比较好的,可以查看原文,原文地址是:http://www.rabbitmq.com/tutorials/tutorial-five-dotnet.html
【c#】RabbitMQ学习文档(五)Topic(主题。通配符模式)的更多相关文章
- 【c#】RabbitMQ学习文档(一)Hello World
一.简介 RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到邮筒之时,你可以确定的是邮递员先生肯定会把邮件发送到需要接收邮件的人的手里,不 ...
- 【c#】RabbitMQ学习文档(七)C# API
今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. Net/C# 客户端 API简介 主要的命名空间,接口和类 定义核心的API的接口 ...
- 【c#】RabbitMQ学习文档(三)Publish/Subscribe(发布/订阅)
(本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向多个 ...
- 【c#】RabbitMQ学习文档(六)RPC(远程调用)
远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...
- 【c#】RabbitMQ学习文档(四)Routing(路由)
(使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ,这个功能是我们将只订阅消息的一个子集成为可能. 例 ...
- 【c#】RabbitMQ学习文档(二)Work Queues(工作队列)
今天开始RabbitMQ教程的第二讲,废话不多说,直接进入话题. (使用.NET 客户端 进行事例演示) 在第一个教程中,我们编写了一个从命名队列中发送和接收消息的程序. ...
- Ext JS 6学习文档-第8章-主题和响应式设计
Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...
- RabbitMq 技术文档
RabbitMq 技术文档 目录 1 AMQP简介 2 AMQP的实现 3 RabbitMQ简介 3.1 概念说明 3.2 消息队列的使用过程 3.3 RabbitMQ的特性 4 RabbitMQ使用 ...
- soapUI学习文档(转载)
soapUI 学习文档不是前言的前言记得一个搞开发的同事突然跑来叫能不能做个WebService 性能测试,当时我就凌乱了,不淡定啊,因为我是做测试的,以前连WebService 是什么不知道,毕竟咱 ...
随机推荐
- 关于阿里ICON矢量图(SVG)上传问题.
注意点: 1. 存储为svg格式(建议使用存储为svg,不要使用导出为svg)2. 图像位置:链接(注意哦,不要点嵌入和保留编辑功能)---确定3. AI里面选中图形,点对象-路径-轮廓化描边 软件编 ...
- Navicat Premium 12 (64位)实现连接Oracle 11 (64位)
查看Oracle的版本 select * from v$version 我这里是11.2的64位的版本,然后从官网下载相应版本的客户端. 下载相应版本的客户端 官网地址:https://www.ora ...
- Linux正则表达式练习
练习一 1.生成30位的随机口令 [root@centos7 ~]#cat /dev/urandom | tr -dc "[:alnum:]" | head -c30 RJL5qc ...
- myeclipse中的HTML页面在浏览器中显示为乱码
myeclipse中的HTML页面在浏览器中显示为乱码 在通过myeclipse开发项目的过程中,如果用HTML页面书写前端,可能出现中文乱码现象,需要怎么解决呢?下面是我从网上搜的方法: 解决办法: ...
- oracle 报错无法从套接字获取更多数据
报错信息如下: ---查看_optimizer_join_elimination_enabled参数值 切换sys用户 select a.ksppinm name, b.ksppstvl value, ...
- 解决挂载nfs共享目录失败的问题
现象:在192.168.82.131上 启动了nfs服务,并共享了/nfsfile目录,在另一台主机(ip: 192.1168.82.115)挂载的时候一直阻塞 1 初步分析是防火墙拦截导致,于是进行 ...
- HTTP Status 500 - Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
今天整合ssm框架 时 遇到的问题 困扰我好长时间 原因就是 mapper文件 没有被加载进来 但是 为什么没有被加载进来呢 因为中间的配置文件出了一些问题 网上大多数说法是 在pom ...
- Android Studio 设置不同分辨率的图标Icon
右键你的项目 -->"NEW"-->"Image Asset" 'Asset Type' 勾选”Image“才可以选择”Path“,其他选项可以自己 ...
- 解决idea中 mvn项目导了包找不到包的问题
----------------------------------------分割线--------------------------------------------------------- ...
- 对象池----unity中应用
对象池应用在unity中能减少资源消耗,节省内存空间具体原理不再赘述. 以下是他的操作步骤:(注意:对象池中应用到了栈或对队列!) 1).先建立一个(怪物)物体 mMonster; 2).再建立一 ...