先决条件
本教程假定 RabbitMQ 已经安装,并运行在localhost
标准端口(5672)。若是你使用不一样的主机、端口或证书,则须要调整链接设置。html从哪里得到帮助
若是您在阅读本教程时遇到困难,能够经过邮件列表 联系咱们。git
RabbitMQ 是一个消息中间件:它接收并转发消息。您能够把它想象为一个邮局:当您把须要寄出的邮件投递到邮箱,邮差最终会把邮件送给您的收件人。在这个比喻中,RabbitMQ 就是一个邮箱,也能够理解成邮局和邮递员。github
RabbitMQ 和邮局的主要区别在于它不处理纸张,而是接收、存储和转发二进制数据块 - 消息。shell
RabbitMQ 和消息传递一般使用一些术语。windows
生产 的意思无非就是发送。发送消息的程序就是一个 生产者:数组
队列 就是 RabbitMQ 内部“邮箱”的名称。虽然消息流经 RabbitMQ 和您的应用程序,但它们只能存储在 队列 中。队列 只受主机的内存和磁盘的限制,它本质上就是一个很大的消息缓冲区。多个 生产者 能够发送消息到一个队列,而且多个 消费者 能够尝试从一个 队列 接收数据。这就是咱们表明队列的方式:服务器
消费 与接收有类似的含义,等待接收消息的程序就是一个 消费者:异步
注意:生产者、消费者和中间件不是必须部署在同一主机上,实际上在大多数应用程序中它们也不是这样的。工具
使用 .NET / C#Clientgoogle
在教程的这一部分,咱们将用 C# 编写两个程序:一个发送单条消息的生产者,以及接收消息并将其打印出来的消费者。咱们将忽略 .NET 客户端 API 中的一些细节,专一于更简单的开始。这是一个消息传递的“Hello World”。
在下图中,P
是咱们的生产者,C
是咱们的消费者。中间的盒子是队列 - RabbitMQ 表明消费者保存的消息缓冲区。
.NET 客户端库
RabbitMQ 支持多种协议,本教程使用
AMQP 0-9-1
,它是一种开放的、通用的消息传递协议。RabbitMQ 提供了一些针对不一样 语言环境 的客户端,咱们将使用 RabbitMQ 提供的 .NET 客户端。客户端支持 .NET Core 以及 .NET Framework 4.5.1+。本教程将使用 .NET Core,所以您须要确保客户端已 安装 而且路径添加到
PATH
系统变量。您也可使用 .NET Framework 来完成本教程,但设置步骤会有所不一样。
RabbitMQ .NET 客户端 5.0 及更高版本经过 nuget 发布。
本教程假定您在 Windows 上使用 PowerShell。在 MacOS 和 Linux 上,几乎全部 shell 也均可以正常工做。
首先让咱们验证您在PATH
系统变量是否有 .NET Core 工具链:
dotnet --help
应该产生帮助信息。
如今,让咱们生成两个项目,一个用于发布者,另外一个用于消费者:
dotnet new console --name Send mv Send/Program.cs Send/Send.cs dotnet new console --name Receive mv Receive/Program.cs Receive/Receive.cs
这将建立两个名为Send
和Receive
的新目录。
而后,咱们添加客户端依赖项。
cd Send dotnet add package RabbitMQ.Client dotnet restore cd ../Receive dotnet add package RabbitMQ.Client dotnet restore
咱们已经创建了 .NET 项目,如今咱们能够编写一些代码。
咱们将调用咱们的消息发布者(发送者)Send.cs
和咱们的消息消费者(接收者)Receive.cs
。发布者将链接到 RabbitMQ,发送一条消息,而后退出。
在 Send.cs 中,咱们须要使用一些命名空间:
using System; using RabbitMQ.Client; using System.Text;
设置类:
class Send { public static void Main() { ... } }
而后,咱们能够建立一个链接,链接到服务器:
class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { ... } } } }
该链接抽象了套接字链接,并为咱们处理协议版本的协商和身份验证等。在这里,咱们链接的是本地机器上的代理, 所以是localhost
。若是咱们想链接到其余机器上的代理,咱们只需在此指定其名称或 IP 地址。
接下来,咱们建立一个通道,该 API 的主要功能是把得到信息保存起来。
想要发送消息,咱们必须为须要发送的消息声明一个队列,而后咱们就能够把消息发布到队列中:
using System; using RabbitMQ.Client; using System.Text; class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } }
声明队列是 幂等 的 - 只有当它不存在时才会被建立。消息内容是一个字节数组,因此您能够用喜欢的任意方式编码。
当上面的代码完成运行时,通道和链接将被释放。这就是咱们的发布者。
(Send.cs 源码)
发送不起做用!
若是这是您第一次使用 RabbitMQ,而且您没有看到“已发送”消息,那么您可能会挠着头想知道错误出在什么地方。也许是代理程序启动时没有足够的可用磁盘空间(默认状况下,它至少须要50 MB空闲空间),所以拒绝接收消息。 必要时检查代理程序日志文件来确认和减小限制。配置文件 文档 将告诉您如何设置
disk_free_limit
。
至于消费者,它是把消息从 RabbitMQ 拉取过来。所以,与发布消息的发布者不一样,咱们会保持消费者持续不断地运行,监听消息并将其打印出来。
代码(在 Receive.cs 中)具备与Send
差很少同样的using
声明:
using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text;
设置与发布者相同;咱们开启一个链接和一个通道,并声明咱们将要使用的队列。请注意,这须要与Send
发布到的队列相匹配。
class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); ... } } } }
请注意,咱们在这里也声明了队列。由于咱们可能会在发布者以前启动消费者,因此咱们但愿在咱们尝试从它中消费消息以前确保队列已存在。
咱们即将告诉服务器将队列中的消息传递给咱们。因为它会异步推送消息,所以咱们提供了一个回调。这就是EventingBasicConsumer.Received
事件处理程序所作的事情。
using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text; class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }
(Receive.cs 源码)
打开两个终端。
运行消费者:
cd Receive dotnet run
运行生产者:
cd Send dotnet run
消费者将打印它经过 RabbitMQ 从发布者处得到的消息。消费者将继续运行、等待新消息(按Ctrl-C
将其中止),能够尝试从开启另外一个终端运行发布者。
接下来能够跳转到 教程[2],构建一个简单的工做队列。
本文翻译自 RabbitMQ 官方教程 C# 版本。如本文介绍内容与官方有所出入,请以官方最新内容为准。水平有限,翻译的很差请见谅,若有翻译错误还请指正。