热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【译】RabbitMQ:"HelloWorld"

RabbitMQ是一个消息代理。从本质上讲,它从消息生产者处接收消息,然后传递给消息的消费者。它在消息的生产者和消费者之间根据你指定的规则对消息进行路由、缓存和持久化。Rabbit

  RabbitMQ是一个消息代理。从本质上讲,它从消息生产者处接收消息,然后传递给消息的消费者。它在消息的生产者和消费者之间根据你指定的规则对消息进行路由、缓存和持久化。

RabbitMQ通常使用如下术语:

  • 生产(Producing),表示消息的发送。发送消息的程序被称为生产者。我们画一个图来表示它,如下所示:

 

                      【译】RabbitMQ:"Hello World"

  • 队列(Queue),表示邮箱的名称,它存在于RabbitMQ服务器中。尽管消息在RabbitMQ和你的应用程序间流转,但它们只能存储与RabbitMQ内部的队列中。队列不会有任何限制,它可以存放任意多的消息,就像一个无限量的缓存一般。多个生产者可以向同一个队列发送消息,多个消费者也可以尝试从同一个队列中读取消息。一个队列可以被画成下面这样在其上有一个名称的图形:

                    【译】RabbitMQ:"Hello World"

  • 消费(Consuming),表示消息的接收。消费者表示通常都在等待接收消息的程序。画图的时候给它标记一个“C”:

                      【译】RabbitMQ:"Hello World"

需要注意的是,生产者、消费者和代理并不必驻留于同一个服务器上面;通常情况下,他们是分部在不同的机器上面的。

Hello World

使用.NET/C#客户端

在教程的这一部分,我们将用C#写两个程序;一个发送一条信息的生产者和一个接收并打印消息的消费者。我们会略过.NET API的一些细节,仅仅专注于如何完成这个简单的程序,传输内容为“Hello World”的消息。

下图中,“P”表示生产者,“C”表示消费者。中间的方框,表示一个队列--RabbitMQ为消费者提供的一个消息缓存。

           【译】RabbitMQ:"Hello World"

.NET 客户端库

RabbitMQ遵循AMQP协议,一个关于消息发送的开放、通用协议。现在已经有很多不同编程语言实现的AMQP的客户端。我们将使用由RabbitMQ提供的.NET客户端。

下载客户端库的包,按照描述去检查它的签名。提取包的内容,把“RabbitMQ.Client.dll”程序集复制到你的工作目录下。

你需要确认你的系统中能找到C#的编译器csc.exe,你可能需要把目录“;C:\WINDOWS\Microsoft.NET\Framework\v3.5”(需要根据你实际的安装情况,修改目录中.NET版本)添加到你的Path中。

 

现在我们已经有了.NET客户端的二进制程序,可以写些代码了。

发送(Sending

                  【译】RabbitMQ:"Hello World"

我们把消息的发送者称为Send.cs,消息的接收者称为Receive.cs。消息发送者将连接到RabbitMQ,发送一条消息,然后退出。

Send.cs中,我们需要用到一些命名空间:

1 using System;
2 using RabbitMQ.Client;
3 using System.Text;

设置类

1 class Send
2 {
3     public static void Main()
4     {
5         ...
6     }
7 }

然后创建一个到RabbitMQ服务的链接

 1 class Send
 2 {
 3     public static void Main()
 4     {
 5         var factory = new ConnectionFactory() { HostName = "localhost" };
 6         using (var cOnnection= factory.CreateConnection())
 7         {
 8             using (var channel = connection.CreateModel())
 9             {
10                 ...
11             }
12         }
13     }
14 }

该链接抽象了套接字连接,为我们关注协议版本协定和身份认证等。在这里,我们连接到了一个本地的代理,因此使用的是localhost。如果我们想连接到其他机器的代理,只需要简单在在这里指定该机器的名称或者Ip地址即可。

接下来我们创建信道(Channel),完成工作的很多API都在里面。

为了发送消息,我们必须申明一个队列,然后才能将消息发布其中:

 1 using System;
 2 using RabbitMQ.Client;
 3 using System.Text;
 4 
 5 class Send
 6 {
 7     public static void Main()
 8     {
 9         var factory = new ConnectionFactory() { HostName = "localhost" };
10         using(var cOnnection= factory.CreateConnection())
11         using(var channel = connection.CreateModel())
12         {
13             channel.QueueDeclare(queue: "hello",
14                                  durable: false,
15                                  exclusive: false,
16                                  autoDelete: false,
17                                  arguments: null);
18 
19             string message = "Hello World!";
20             var body = Encoding.UTF8.GetBytes(message);
21 
22             channel.BasicPublish(exchange: "",
23                                  routingKey: "hello",
24                                  basicProperties: null,
25                                  body: body);
26             Console.WriteLine(" [x] Sent {0}", message);
27         }
28 
29         Console.WriteLine(" Press [enter] to exit.");
30         Console.ReadLine();
31     }
32 }

申明一个队列是幂等的,它仅仅会在申明的队列不存在于RabbitMQ中时才被创建。消息的内容是字节数组,所以,你可以使用任何喜欢的方式对消息进行编码。

当上面的代码运行结束,信道和链接将会被释放。

Send.cs的完整代码在这里。

发送无法执行

如果这是你第一次使用RabbitMQ,而且未看到已发送的消息,你一定会搔首疑惑是出了什么问题。也许是因为代理运行在没有足够空闲硬盘空间的机器上(默认情况下,代理需要至少50MB的空闲空间)而导致拒绝接收消息。通过查看代理的日志文件可以确认,同时如果有必要降低该项限制。配置文件文档可以告诉你如何设置(disk_free_limit)。

接收

上面那些是关于发送者的。RabbitMQ将消息压入接收者,所以和发布一条消息的发送者不一样,我们要保持接收者一直运行着去监听消息然后打印出来。

                  【译】RabbitMQ:"Hello World"

Receive.cs的代码需要引用和Send.cs中差不多相同的命名空间:

1 using RabbitMQ.Client;
2 using RabbitMQ.Client.Events;
3 using System;
4 using System.Text;

类的设置和发送者是相同的;我们打开一个链接和一个信道,申明一个我们将要消费的队列。注意队列需要和发送者中申明的队列相匹配。

 1 class Receive
 2 {
 3     public static void Main()
 4     {
 5         var factory = new ConnectionFactory() { HostName = "localhost" };
 6         using (var cOnnection= factory.CreateConnection())
 7         {
 8             using (var channel = connection.CreateModel())
 9             {
10                 channel.QueueDeclare(queue: "hello",
11                                      durable: false,
12                                      exclusive: false,
13                                      autoDelete: false,
14                                      arguments: null);
15                 ...
16             }
17         }
18     }
19 }

注意在这里申明的这个队列。我们可能在运行发送者前运行接收者,需要确保在消费这个队列之前队列已经存在。

我们将要告诉RabbitMQ服务从哪个队列传递消息给我们。因为该队列将压入异步消息给我们,我们提供回调。这就是EveningBasicConsumer.Received事件处理器做的事情了。

 1 using RabbitMQ.Client;
 2 using RabbitMQ.Client.Events;
 3 using System;
 4 using System.Text;
 5 
 6 class Receive
 7 {
 8     public static void Main()
 9     {
10         var factory = new ConnectionFactory() { HostName = "localhost" };
11         using(var cOnnection= factory.CreateConnection())
12         using(var channel = connection.CreateModel())
13         {
14             channel.QueueDeclare(queue: "hello",
15                                  durable: false,
16                                  exclusive: false,
17                                  autoDelete: false,
18                                  arguments: null);
19 
20             var cOnsumer= new EventingBasicConsumer(channel);
21             consumer.Received += (model, ea) =>
22             {
23                 var body = ea.Body;
24                 var message = Encoding.UTF8.GetString(body);
25                 Console.WriteLine(" [x] Received {0}", message);
26             };
27             channel.BasicConsume(queue: "hello",
28                                  noAck: true,
29                                  consumer: consumer);
30 
31             Console.WriteLine(" Press [enter] to exit.");
32             Console.ReadLine();
33         }
34     }
35 }

完整的Receive.cs类在这里。

组合在一起

你可以引用RabbitMQ.NET客户端程序集,然后编译Send.csReceive.cs。我们将使用命令行(cmd.execsc)编译和运行这些代码。或者你可以使用Visual Studio

1 $ csc /r:"RabbitMQ.Client.dll" Send.cs
2 $ csc /r:"RabbitMQ.Client.dll" Receive.cs

然后运行可执行文件

1 $ Send.exe

接着运行接收者

1 $ Receive.exe

接收者会打印从RabbitMQ接收到的消息。接收者一直运行等待新消息(使用Ctrl+C中止),所以可以尝试在不同的终端运行发送者。

如果你希望在队列上做检查,使用rabbitmqctl list_queues.

Hello World!

 

现在是时候进入到第二部分去创建一个工作队列了。

 

原文链接:http://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html


推荐阅读
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 如何撰写适应变化的高效代码:策略与实践
    编写高质量且适应变化的代码是每位程序员的追求。优质代码的关键在于其可维护性和可扩展性。本文将从面向对象编程的角度出发,探讨实现这一目标的具体策略与实践方法,帮助开发者提升代码效率和灵活性。 ... [详细]
  • Codeforces竞赛解析:Educational Round 84(Div. 2评级),题目A:奇数和问题
    Codeforces竞赛解析:Educational Round 84(Div. 2评级),题目A:奇数和问题 ... [详细]
  • 在使用 Cacti 进行监控时,发现已运行的转码机未产生流量,导致 Cacti 监控界面显示该转码机处于宕机状态。进一步检查 Cacti 日志,发现数据库中存在 SQL 查询失败的问题,错误代码为 145。此问题可能是由于数据库表损坏或索引失效所致,建议对相关表进行修复操作以恢复监控功能。 ... [详细]
  • Unity与MySQL连接过程中出现的新挑战及解决方案探析 ... [详细]
  • OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战
    OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 深入理解Java中的多态性概念及其应用
    多态是面向对象编程中的三大核心特性之一,与封装和继承共同构成了面向对象的基础。多态使得代码更加灵活和可扩展,封装和继承则为其提供了必要的支持。本文将深入探讨多态的概念及其在Java中的具体应用,帮助读者全面理解和掌握这一关键知识点。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
author-avatar
zhaoyan666777
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有