(使用Net客户端)

在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息。

在本教程中,我们将为其添加一项功能 ,这个功能是我们将只订阅消息的一个子集成为可能。 例如,我们可以只将关键的错误消息输出到日志文件(以节省磁盘空间),同时仍然可以在控制台上打印所有日志消息。

1、绑定

在以前的例子中,我们已经创建了绑定。 你可能会记得如下代码:

channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");

【绑定】是【消息交换机】和【队列】之间的关系纽带,通过绑定把二者关联起来。 这可以简单地理解为:队列可以接收来自此【消息交换机】的消息。

【绑定】可以占用额外的路由选择参数。 为了避免与BasicPublish参数混淆,我们将其称为【绑定键】。 以下代码就是如何用一个键值来创建一个绑定:

channel.QueueBind(queue: queueName,
exchange: "direct_logs",
routingKey: "black");

【绑定键】的含义取决于交换类型。 以前我们使用的【Fanout】类型的【消息交换机】忽略了它的取值。

2、直接交换

在上一个教程中,我们的日志记录系统向所有【消费者】发送所有消息。 我们希望将其扩展为允许基于其严重性过滤消息。 例如,我们可能希望将写入磁盘日志消息的脚本仅接受严重错误,而不会在警告或信息日志消息上浪费磁盘空间。

我们正在使用一个【Fanout】类型的【消息交换机】,它不会给我们带来很大的灵活性 - 它只能无意识地发送。

我们将使用一个【Direct】类型的【消息交换机】。 直接转换路由的背后的算法其实是很简单的 - 把消息传递到【绑定键 binding key】和消息的【路由键 routing key】完全匹配的队列中。

为了说明,请考虑以下设置:

在这个设置中,我们可以看到【Direct】类型的【消息交换机】X与两个队列相绑定。 第一个队列与【绑定键】的值是Orange相绑定的,第二个队列有两个绑定,一个【绑定键】的值是black,另一个【绑定键】的值是green。

在这样的设置中,发布到具有【路由键】为orange的【消息交换机】的消息将被路由到队列Q1。 具有black或green【路由键】的消息将转到Q2。 所有其他消息将被丢弃。

3、多重绑定

      

使用相同的【绑定键】绑定多个队列是完全合法的。 在我们的示例中,我们可以在X和Q1之间添加【绑定键】是black的绑定。 在这种情况下,【direct】类型的【消息交换机】将表现得像【Fanout】类型的【消息交换机】,并将消息发送到所有匹配的队列。 具有【路由键】是black的消息将传送到Q1和Q2。

4、发出日志

我们将发送消息到【Direct】类型的【消息交换机】来替换【fanout】类型的【消息交换机】,在我们现在的日志系统将使用此模型。 我们将提供日志严重性作为【路由键】。 这样接收脚本就能够选择想要接收的严重性。 我们首先关注发出日志。

像以前一样,我们首先要建立一个【消息交换机】:

channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");

现在,我们准备发送消息:

var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "direct_logs",
routingKey: severity,
basicProperties: null,
body: body);

为了简化事情,我们假设“严重性”可以是“信息”,“警告”,“错误”之一。

5、订阅

接收消息将像上一个教程一样工作,除了一个例外 - 我们将为每个我们感兴趣的严重性创建一个新的绑定。

var queueName = channel.QueueDeclare().QueueName;

foreach(var severity in args)
{
channel.QueueBind(queue: queueName,
exchange: "direct_logs",
routingKey: severity);
}

6、整合

以下是EmitLogDirect.cs类的代码:

 using System;
using System.Linq;
using RabbitMQ.Client;
using System.Text; class EmitLogDirect
{
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: "direct_logs",
type: "direct"); var severity = (args.Length > ) ? args[] : "info";
var message = (args.Length > )
? string.Join(" ", args.Skip( ).ToArray())
: "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "direct_logs",
routingKey: severity,
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent '{0}':'{1}'", severity, message);
} Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}

以下是ReceiveLogsDirect.cs类的代码:

 using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text; class ReceiveLogsDirect
{
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: "direct_logs",
type: "direct");
var queueName = channel.QueueDeclare().QueueName; if(args.Length < )
{
Console.Error.WriteLine("Usage: {0} [info] [warning] [error]",
Environment.GetCommandLineArgs()[]);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
Environment.ExitCode = ;
return;
} foreach(var severity in args)
{
channel.QueueBind(queue: queueName,
exchange: "direct_logs",
routingKey: severity);
} Console.WriteLine(" [*] Waiting for messages."); 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();
}
}
}

如果您只想将“警告”和“错误”(而不是“信息”)保存到文件中,只需打开控制台并键入:

cd ReceiveLogsDirect
dotnet run warning error > logs_from_rabbit.log

如果您想查看屏幕上的所有日志消息,请打开一个新终端,然后执行以下操作:

cd ReceiveLogsDirect
dotnet run info warning error
# => [*] Waiting for logs. To exit press CTRL+C

而且,例如,要发出错误日志消息,只需键入:

cd EmitLogDirect
dotnet run error "Run. Run. Or it will explode."
# => [x] Sent 'error':'Run. Run. Or it will explode.'

以下是原文地址:http://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html

今天这篇文章终于翻译完了,整个系列还有几篇没翻译。英文水平有限,错误在所难免,欢迎大家提出来,共同学习。

RabbitMQ系列教程之四:路由(Routing)的更多相关文章

  1. RabbitMQ系列教程之四:路由(Routing)(转载)

    RabbitMQ系列教程之四:路由(Routing) (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ...

  2. RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介(转载)

    RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介 今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. N ...

  3. RabbitMQ系列教程之五:主题(Topic)(转载)

    RabbitMQ系列教程之五:主题(Topic) (本实例都是使用的Net的客户端,使用C#编写),说明,中文方括号[]表示名词. 在上一个教程中,我们改进了我们的日志记录系统. 没有使用只能够进行虚 ...

  4. RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)(转载)

    RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe) (本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个 ...

  5. RabbitMQ系列教程之六:远程过程调用(RPC)(转载)

    RabbitMQ系列教程之六:远程过程调用(RPC) 远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习 ...

  6. RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World(转载)

    RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World 一.简介 RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到 ...

  7. 2.rabbitmq 系列教程

    rabbitmq系列教程-文章[转] 视频分享: 链接:https://pan.baidu.com/s/1s_Qr2A1o0s8Ru0exK62jqg 提取码:eb68

  8. RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)

    (本教程是使用Net客户端,也就是针对微软技术平台的)   在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向 ...

  9. RabbitMQ系列教程之五:主题(Topic)

    (本实例都是使用的Net的客户端,使用C#编写),说明,中文方括号[]表示名词.   在上一个教程中,我们改进了我们的日志记录系统. 没有使用只能够进行虚拟广播的[Fanout]交换机,而是使用了[D ...

随机推荐

  1. 运用三角不等式加速Kmeans聚类算法

    运用三角不等式加速Kmeans聚类算法 引言:最近在刷<数据挖掘导论>,第九章, 9.5.1小节有提到,可以用三角不等式,减少不必要的距离计算,从而达到加速聚类算法的目的.这在超大数据量的 ...

  2. hdu2196Computer 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 思路: 一看就是一道树形DP的题目,对于一个节点来说,到它的最远距离的路径可能来于子树,也可能来 ...

  3. 神经网络结构在命名实体识别(NER)中的应用

    神经网络结构在命名实体识别(NER)中的应用 近年来,基于神经网络的深度学习方法在自然语言处理领域已经取得了不少进展.作为NLP领域的基础任务-命名实体识别(Named Entity Recognit ...

  4. 回答集编程背景(Answer Set Programming)

    毕业设计跟的导师是研究计算机理论的,花了三个月学习符号逻辑,试图优化一个回答集程序的求解器(Answer set solver).比起眼花缭乱的前端框架和热闹的社区讨论,符号逻辑就是一个挺小众的数学领 ...

  5. java swing 添加 jcheckbox复选框

    总体上而言,Java Swing编程有两大特点:麻烦.效果差. 麻烦是说由于设计器的使用不方便(如果您希望使用窗体设计器通过快速拖拽控件建立您的Java Swing GUI程序,请您使用MyEclip ...

  6. 在Excel上写程序(ExcelEx)

    首先要说明的是:Ctrl+D,是执行框选的的扩展函数+号,一个单元格里多个函数用+号分隔*号,相当于链式操作(没法子,公式里不能写"."号) 虽还有很大的局限性,至少很多小程序和数 ...

  7. python 计算两个日期相差多少个月

    近期,由于业务需要计算两个日期之前相差多少个月.我在网上找了很久,结果发现万能的python,居然没有一个模块计算两个日期的月数,像Java.C#之类的高级语言,都会有(date1-date2).mo ...

  8. (基础篇 走进javaNIO)第一章-java的i/o演进之路

    Java 是由 SUN公司在 1995 年首先发布 的编程语 言和计算平 台.这基础技术 支持最新 的程序 ,包括 实用程序 .游 戏和业 务应用程序 .J ava 在世界各地 的 8.5  亿 多 ...

  9. TensorFlow for R

    TensorFlow™ is an open source software library for numerical computation using data flow graphs. Nod ...

  10. C#基础篇--面向对象(类与对象)

    1.类是什么?  类就相当于模板,就是把同一类的事物的共同特征进行的抽象. 类的创建和说明: 类是先根据一些具体的对象(实体的东西)来抽象出来的共同的特性,然后用代码来表示. 在类中,用数据表示事物的 ...