[译]RabbitMQ教程C#版 - "Hello World"

简介: 先决条件本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672)。如果你使用不同的主机、端口或证书,则需要调整连接设置。从哪里获得帮助如果您在阅读本教程时遇到困难,可以通过邮件列表 联系我们。

先决条件
本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672)。如果你使用不同的主机、端口或证书,则需要调整连接设置。

从哪里获得帮助
如果您在阅读本教程时遇到困难,可以通过邮件列表 联系我们

介绍

RabbitMQ是一个消息中间件:它接收并转发消息。您可以把它想象为一个邮局:当您把需要寄出的邮件投递到邮箱,邮差最终会把邮件送给您的收件人。在这个比喻中,RabbitMQ就是一个邮箱,也可以理解成邮局和邮递员。

RabbitMQ和邮局的主要区别在于它不处理纸张,而是接收、存储和转发二进制数据块 - 消息

RabbitMQ和消息传递通常使用一些术语。

生产的意思无非就是发送。发送消息的程序就是一个生产者

Producer

队列就是RabbitMQ内部“邮箱”的名称。虽然消息流经RabbitMQ和您的应用程序,但它们只能存储在队列中。队列只受主机的内存和磁盘的限制,它本质上就是一个很大的消息缓冲区。多个生产者可以发送消息到一个队列,并且多个消费者可以尝试从一个队列接收数据。这就是我们代表队列的方式:

Queue

消费与接收有相似的含义。主要等待接收消息的程序就是一个消费者

Consumer

注意:生产者、消费者和中间件不是必须部署在同一主机上,实际上在大多数应用程序中它们不是。

"Hello World"

使用.NET / C#Client

在教程的这一部分,我们将用C#编写两个程序:一个发送单条消息的生产者,以及接收消息并将其打印出来的消费者。我们将忽略.NET客户端API中的一些细节,专注于更简单的开始。这是一个消息传递的“Hello World”。

在下图中,P是我们的生产者,C是我们的消费者。中间的盒子是队列 - RabbitMQ代表消费者保存的消息缓冲区。

image

.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

这将创建两个名为SendReceive的新目录。

然后,我们添加客户端依赖项。

cd Send
dotnet add package RabbitMQ.Client
dotnet restore
cd ../Receive
dotnet add package RabbitMQ.Client
dotnet restore

我们已经建立了.NET项目,现在我们可以编写一些代码。

发送

Sending

我们将调用我们的消息发布者(发送者)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拉取过来。因此,与发布消息的发布者不同,我们会保持消费者持续不断地运行,监听消息并将其打印出来。

Receiving

代码(在 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#版本。如本文介绍内容与官方有所出入,请以官方最新内容为准。水平有限,翻译的不好请见谅,如有翻译错误还请指正。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
1月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
|
6月前
|
消息中间件 Java RocketMQ
RocketMQ实战教程之RocketMQ安装
这是一篇关于RocketMQ安装的实战教程,主要介绍了在CentOS系统上使用传统安装和Docker两种方式安装RocketMQ。首先,系统需要是64位,并且已经安装了JDK 1.8。传统安装包括下载安装包,解压并启动NameServer和Broker。Docker安装则涉及安装docker和docker-compose,然后通过docker-compose.yaml文件配置并启动服务。教程还提供了启动命令和解决问题的提示。
|
1月前
|
消息中间件 存储 JSON
rabbitmq基础教程(ui,java,springamqp)
本文提供了RabbitMQ的基础教程,包括如何使用UI创建队列和交换机、Java代码操作RabbitMQ、Spring AMQP进行消息发送和接收,以及如何使用不同的交换机类型(fanout、direct、topic)进行消息路由。
24 0
rabbitmq基础教程(ui,java,springamqp)
|
6月前
|
消息中间件 前端开发 数据库
RocketMQ实战教程之MQ简介与应用场景
RocketMQ实战教程介绍了MQ的基本概念和应用场景。MQ(消息队列)是生产者和消费者模型,用于异步传输数据,实现系统解耦。消息中间件在生产者发送消息和消费者接收消息之间起到邮箱作用,简化通信。主要应用场景包括:1)应用解耦,如订单系统与库存系统的非直接交互;2)异步处理,如用户注册后的邮件和短信发送延迟处理,提高响应速度;3)流量削峰,如秒杀活动限制并发流量,防止系统崩溃。
|
2月前
|
设计模式 C# 开发者
C#设计模式入门实战教程
C#设计模式入门实战教程
|
3月前
|
网络协议 物联网 测试技术
App Inventor 2 MQTT拓展入门(保姆级教程)
本文演示的是App和一个测试客户端进行消息交互的案例,实际应用中,我们的测试客户端可以看着是任意的、支持MQTT协议的硬件,通过订阅及发布消息,联网硬件与我们的App进行双向数据通信,以实现万物互联的智能控制效果。
198 2
|
3月前
|
消息中间件 监控 Ubuntu
RabbitMQ安装配置,超详细版教程
以上步骤为您提供了在Linux环境下安装RabbitMQ的详细过程。安装Erlang作为基础,然后通过添加官方源并安装RabbitMQ本身,最后对服务进行配置并启用Web管理界面。这些步骤操作简单直观,只需要跟随上述指南,即可在短时间内将RabbitMQ服务器运行起来,并进行进一步的配置和管理。不要忘记硬件和网络资源对性能的影响,确保RabbitMQ能够满足您的应用需求。
252 0
|
4月前
|
机器学习/深度学习 算法 搜索推荐
一个开源且全面的C#算法实战教程
一个开源且全面的C#算法实战教程
|
6月前
|
消息中间件 存储 Apache
RocketMQ实战教程之常见概念和模型
Apache RocketMQ 实战教程介绍了其核心概念和模型。消息是基本的数据传输单元,主题是消息的分类容器,支持字节、数字和短划线命名,最长64个字符。消息类型包括普通、顺序、事务和定时/延时消息。消息队列是实际存储和传输消息的容器,是主题的分区。消费者分组是一组行为一致的消费者的逻辑集合,也有命名限制。此外,文档还提到了一些使用约束和建议,如主题和消费者组名的命名规则,消息大小限制,请求超时时间等。RocketMQ 提供了多种消息模型,包括发布/订阅模型,有助于理解和优化消息处理。
|
6月前
|
消息中间件 存储 Java
RocketMQ实战教程之NameServer与BrokerServer
这是一个关于RocketMQ实战教程的概要,主要讨论NameServer和BrokerServer的角色。NameServer负责管理所有BrokerServer,而BrokerServer存储和传输消息。生产者和消费者通过NameServer找到合适的Broker进行交互,不需要直接知道Broker的具体信息。工作流程包括生产者向NameServer查询后发送消息到Broker,以及消费者同样通过NameServer获取消息进行消费。这种设计类似于服务注册中心的概念,便于系统扩展和集群管理。