[译]RabbitMQ教程C#版 - "Hello World"
先决条件
本教程假定 RabbitMQ 已经安装,并运行在localhost
标准端口(5672)。如果你使用不同的主机、端口或证书,则需要调整连接设置。从哪里获得帮助
如果您在阅读本教程时遇到困难,可以通过邮件列表 联系我们。
介绍
RabbitMQ 是一个消息中间件:它接收并转发消息。您可以把它想象为一个邮局:当您把需要寄出的邮件投递到邮箱,邮差最终会把邮件送给您的收件人。在这个比喻中,RabbitMQ 就是一个邮箱,也可以理解成邮局和邮递员。
RabbitMQ 和邮局的主要区别在于它不处理纸张,而是接收、存储和转发二进制数据块 - 消息。
RabbitMQ 和消息传递通常使用一些术语。
生产 的意思无非就是发送。发送消息的程序就是一个 生产者:
队列 就是 RabbitMQ 内部“邮箱”的名称。虽然消息流经 RabbitMQ 和您的应用程序,但它们只能存储在 队列 中。队列 只受主机的内存和磁盘的限制,它本质上就是一个很大的消息缓冲区。多个 生产者 可以发送消息到一个队列,并且多个 消费者 可以尝试从一个 队列 接收数据。这就是我们代表队列的方式:
消费 与接收有相似的含义,等待接收消息的程序就是一个 消费者:
注意:生产者、消费者和中间件不是必须部署在同一主机上,实际上在大多数应用程序中它们也不是这样的。
"Hello World"
使用 .NET / C#Client
在教程的这一部分,我们将用 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# 版本。如本文介绍内容与官方有所出入,请以官方最新内容为准。水平有限,翻译的不好请见谅,如有翻译错误还请指正。
- 原文链接:RabbitMQ tutorial - "Hello World!"
- 实验环境:RabbitMQ 3.7.4 、.NET Core 2.1.3、Visual Studio Code
- 最后更新:2018-03-13
[译]RabbitMQ教程C#版 - "Hello World"的更多相关文章
- [译]RabbitMQ教程C#版 - “Hello World”
[译]RabbitMQ教程C#版 - “Hello World” 先决条件本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需 ...
- [译]RabbitMQ教程C#版 - 工作队列
先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...
- [译]RabbitMQ教程C#版 - 远程过程调用(RPC)
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 主题
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 路由
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 发布订阅
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- RabbitMQ教程C#版 - Hello World
先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...
- RabbitMQ教程C#版 - 发布订阅
先决条件本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助如果您在阅读本教程时遇到困难,可以 ...
- RabbitMQ教程C#版 - 工作队列
先决条件本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助如果您在阅读本教程时遇到困难,可以 ...
随机推荐
- char 与 varchar 区别
MySQL中的字符串有两个常用的类型:char和varchar,二者各有优势,下面我们来详细分析一下. 转载加补充 在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类 ...
- 《JAVA编程思想》第四版 PDF
感谢,参考:https://www.cnblogs.com/buwuliao/p/8073211.html 一.链接: 中文版: https://pan.baidu.com/s/1d07Kp4 密码: ...
- 基于bootstrap-treeview做的一个漂亮的无限分类树层级联动菜单
2017年12月11日09:59:15 因为工作需要把原来的bootstrap-treeview做了一些小改动,方便后台开发人员使用 最终效果,看起来还行,但是其实不是特别友好对用户来说,但是对开发者 ...
- virtualenv与virtualenvwrapper虚拟环境
python开发之virtualenv与virtualenvwrapper讲解 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物 ...
- Hyper-v带宽限制以及验证工具
最近在做项目的性能测试时,需要模拟网络的带宽来控制文件的上传速度.按照以前的方式方法,我们一般会使用工具 softperfect bandwidth manager 来模拟上下行的带宽. 官网地址 h ...
- Emmet.vim 教程
Emmet.vim 教程 May 5, 2012 目录 1 下载 Emmet.vim 2 安装 Emmet.vim 3 使用 Emmet.vim 4 余话 Emmet 项目原先叫 Zen Coding ...
- PHP中new self()和new static()的区别探究
1.new static()是在PHP5.3版本中引入的新特性. 2.无论是new static()还是new self(),都是new了一个新的对象. 3.这两个方法new出来的对象有什么区别呢,说 ...
- 创建视图sql
create view 视图名称 as 查询sql语句create view test2 as select * from sc te ...
- openshift 容器云从入门到崩溃之九《容器监控-报警》
容器状态监控 主要是监控POD的状态包括重启.不健康等等这些k8s api 状态本身会报出来,在配合zabbix报警 导入zabbix模板关联上oc master主机 <?xml version ...
- windows----------自启动QQ报错”initialization failure:0x0000000C“
1.从来没遇到过这个问题,不知道为啥最近竟然遇到了两次,家里的电脑和公司的电脑都这样. 通过百度得知答案,并亲自试过了,是正确的解决方法: 原因:上次没有正常关机导致的错误 方法:管理员运行cmd ...