(使用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类的代码:

 1 using System;
2 using System.Linq;
3 using RabbitMQ.Client;
4 using System.Text;
5
6 class EmitLogDirect
7 {
8 public static void Main(string[] args)
9 {
10 var factory = new ConnectionFactory() { HostName = "localhost" };
11 using(var connection = factory.CreateConnection())
12 using(var channel = connection.CreateModel())
13 {
14 channel.ExchangeDeclare(exchange: "direct_logs",
15 type: "direct");
16
17 var severity = (args.Length > 0) ? args[0] : "info";
18 var message = (args.Length > 1)
19 ? string.Join(" ", args.Skip( 1 ).ToArray())
20 : "Hello World!";
21 var body = Encoding.UTF8.GetBytes(message);
22 channel.BasicPublish(exchange: "direct_logs",
23 routingKey: severity,
24 basicProperties: null,
25 body: body);
26 Console.WriteLine(" [x] Sent '{0}':'{1}'", severity, message);
27 }
28
29 Console.WriteLine(" Press [enter] to exit.");
30 Console.ReadLine();
31 }
32 }

以下是ReceiveLogsDirect.cs类的代码:

 1 using System;
2 using RabbitMQ.Client;
3 using RabbitMQ.Client.Events;
4 using System.Text;
5
6 class ReceiveLogsDirect
7 {
8 public static void Main(string[] args)
9 {
10 var factory = new ConnectionFactory() { HostName = "localhost" };
11 using(var connection = factory.CreateConnection())
12 using(var channel = connection.CreateModel())
13 {
14 channel.ExchangeDeclare(exchange: "direct_logs",
15 type: "direct");
16 var queueName = channel.QueueDeclare().QueueName;
17
18 if(args.Length < 1)
19 {
20 Console.Error.WriteLine("Usage: {0} [info] [warning] [error]",
21 Environment.GetCommandLineArgs()[0]);
22 Console.WriteLine(" Press [enter] to exit.");
23 Console.ReadLine();
24 Environment.ExitCode = 1;
25 return;
26 }
27
28 foreach(var severity in args)
29 {
30 channel.QueueBind(queue: queueName,
31 exchange: "direct_logs",
32 routingKey: severity);
33 }
34
35 Console.WriteLine(" [*] Waiting for messages.");
36
37 var consumer = new EventingBasicConsumer(channel);
38 consumer.Received += (model, ea) =>
39 {
40 var body = ea.Body;
41 var message = Encoding.UTF8.GetString(body);
42 var routingKey = ea.RoutingKey;
43 Console.WriteLine(" [x] Received '{0}':'{1}'",
44 routingKey, message);
45 };
46 channel.BasicConsume(queue: queueName,
47 noAck: true,
48 consumer: consumer);
49
50 Console.WriteLine(" Press [enter] to exit.");
51 Console.ReadLine();
52 }
53 }
54 }

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

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

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

天下国家,可均也;爵禄,可辞也;白刃,可蹈也;中庸不可能也
 
分类: 消息队列

路由(Routing)的更多相关文章

  1. RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重的错误日 ...

  2. RabbitMQ学习总结 第五篇:路由Routing

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  3. asp.net MVC 5 路由 Routing

    ASP.NET MVC ,一个适用于WEB应用程序的经典模型 model-view-controller 模式.相对于web forms一个单一的整块,asp.net mvc是由连接在一起的各种代码层 ...

  4. AngularJS - 路由 routing 基础示例

    AngularJS 路由 routing 能够从页面的一个视图跳转到另外一个视图,对单页面应用来讲是至关重要的.当应用变得越来越复杂时,我们需要一个合理的方式来管理用户在使用过程中看到的界面.Angu ...

  5. RabbitMQ 入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的第三部分教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重 ...

  6. 路由(Routing)

    路由(Routing)  ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序 ...

  7. RabbitMQ入门:路由(Routing)

    在上一篇博客<RabbitMQ入门:发布/订阅(Publish/Subscribe)>中,我们认识了fanout类型的exchange,它是一种通过广播方式发送消息的路由器,所有和exch ...

  8. Rabbitmq消息队列(五) 路由Routing

    1.简介 在以前一章中,我们可以把一个消息广播给多个接收者.在这一章中,我们会增加一个功能:接收者能够只接收订阅消息中的一个子集. 2.绑定 在我们将交换机和队列进行绑定的时候,我们可以添加一个额外的 ...

  9. ASP.NET Core MVC 之路由(Routing)

     ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序的URL命名形式,使得它 ...

  10. 理解ASP.NET Core - 路由(Routing)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Routing Routing(路由):更准确的应该叫做Endpoint Routing,负责 ...

随机推荐

  1. 数据类型的提升(promotion)

    假如参与运算的数据类型不同或者取值范围过小,编译器会自动将其转换为相同的类型,这个类型就叫数据类型的提升(promotion). 1. C++ 语言环境的规定 unsigned char a = 17 ...

  2. 用Promise对象封装JQuery的AJAX过程

    let jqPostAjaxPromise = function(param){ return new Promise(function(resolve, reject){ $.ajax({ url: ...

  3. 一个简单http请求的jmeter压测实战流程

    1.新建线程组 2.创建http请求 注意:接口路径中的参数值要写变量 3.创建txt文件,存多个参数值 4.创建csv文件,在csv中上传txt文件 5.variable name填写txt中参数值 ...

  4. 初学者路径规划 | 人生苦短我用Python

    纵观编程趋势 人生苦短,我用Python,比起C语言.C#.C++和JAVA这些编程语言相对容易很多.Python非常适合用来入门.有人预言,Python会成为继C++和Java之后的第三个主流编程语 ...

  5. COGS——C 14. [网络流24题] 搭配飞行员

    http://cogs.pro/cogs/problem/problem.php?pid=14 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比时间限制:1 s  ...

  6. jquery如何实现表单post方式提交

    jquery如何实现表单post方式提交 一.总结 一句话总结:即使js给form对象提供了submit()方法,那也不意为表单中可以不写提交按钮这个元素,即form表单依然需要五脏俱全才可以使用js ...

  7. JS学习笔记 - fgm练习 - 网页换肤

    总结: 1. 点击按钮,div内部变色,边框保持颜色不变. 实现原理:其实本来就把background 和 border 分别设置了同一个颜色,看似是一个整体,其实本来就是分开的. 那么点击的时候,只 ...

  8. 【hdu 3518】Boring counting

    [链接]h在这里写链接 [题意] 给出一个字符串,求出至少不重叠出现2次以上的子串有多少个. [题解] 枚举要找的子串的长度i; 根据height数组,找出连续>=i的height; 这几个起始 ...

  9. HDU - 3341 Lost&#39;s revenge(AC自己主动机+DP)

    Description Lost and AekdyCoin are friends. They always play "number game"(A boring game b ...

  10. orabbix 报错No suitable driver found for

     orabbix报错如下:   2018-07-11 14:35:20,119 [main] ERROR Orabbix - Error on Configurator for database qa ...