RabbitMQ教程C#版 “Hello World”

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

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

1.介绍

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

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

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

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

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

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

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

2."Hello World"

2.1.使用.NET / C#客户端

在教程的这一部分,我们将用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也都可以正常工作。

2.2.安装

首先让我们验证您在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 restorecd ../Receivedotnet add package RabbitMQ.Clientdotnet restore

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

2.3.发送

我们将调用我们的消息发布者(发送者)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();} }

声明队列是幂等的 - 只有当它不存在时才会被创建。消息内容是一个字节数组,所以您可以用喜欢的任意方式编码。

当上面的代码完成运行时,通道和连接将被释放。这就是我们的发布者。

发送不起作用!
如果这是您第一次使用RabbitMQ,并且您没有看到“已发送”消息,那么您可能会挠着头想知道错误出在什么地方。也许是代理程序启动时没有足够的可用磁盘空间(默认情况下,它至少需要50 MB空闲空间),因此拒绝接收消息。
必要时检查代理程序日志文件来确认和减少限制。配置文件文档将告诉您如何设置disk_free_limit

2.4.接收

至于消费者,它是把消息从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();}} }

2.5.组合在一起

打开两个终端。

运行消费者:

cd Receive
dotnet run

运行生产者:

cd Send
dotnet run

消费者将打印它通过RabbitMQ从发布者处获得的消息。消费者将继续运行、等待新消息(按Ctrl-C将其停止),可以尝试从开启另一个终端运行发布者。

3.写在最后

本文翻译自RabbitMQ官方教程。水平有限,翻译的不好请见谅,如有翻译错误还请指正。

  • 原文链接:RabbitMQ tutorial - "Hello World!"

  • 实验环境:RabbitMQ 3.7.4 、.NET Core 2.1.3、Visual Studio Code

  • 最后更新:2018-03-13

相关文章: 

  • .net core 使用Redis的发布订阅

  • RabbitMQ知多少

  • RabbitMQ系列教程之四:路由(Routing)

  • RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)

  • RabbitMQ系列教程之二:工作队列(Work Queues)

  • 如何优雅的使用RabbitMQ

  • .NET 使用 RabbitMQ 图文简介

  • RabbitMQ 高可用集群搭建及电商平台使用经验总结

  • .NET Core 使用RabbitMQ

  • ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

原文地址:http://www.cnblogs.com/esofar/p/rabbitmq-hello-world.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S Learning(8)—— Service

一、Service简介 利用Deployment来创建一组Pod来提供具有高可用性的服务,每个Pod都会分配一个单独的Pod IP,却存在以下两个问题: Pod IP 会随着Pod的重建产生变化 Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问 对于访问这个服…

牛客小白月赛18-记录

正题 比赛链接:https://ac.nowcoder.com/acm/contest/1221 成绩 总结 好难,就拿了一些水题分 T1:Forsaken喜欢数论\texttt{T1:Forsaken喜欢数论}T1:Forsaken喜欢数论 题目大意 f(i)f(i)f(i)表示iii的最小质因子,求∑i2nf(i)\sum_{i2}^nf(i)∑i2n​f(i…

.NET Core开源API网关 – Ocelot中文文档

Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。这些功能只都只需要简单的配置即可完成,下面我…

数学题 贪心+二分答案

Description 现在有两个数组 AA 和 BB, 分别包含 xx 与 yy 个元素。 定义一个新的数组 CC, CC 中包含 xyxy 个元素,为 AA 中所有元素除以 BB 中所有元素。 即 新集合为 {c∣cab,a∈A,b∈B}&…

K8S Learning(9)——Pod介绍

一、 Pod结构 每个Pod中都可以包含一个或者多个容器,这些容器分为两类: 用户程序所在的容器,数量没有限制 Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个: 可以以它为依据,评估整个…

NOI.AC-序列【堆】

正题 题目链接:http://noi.ac/contest/266/problem/793 题目大意 给定mmm个函数fz(x)∑i0kaz,i∗xif_z(x)\sum_{i0}^ka_{z,i}*x^ifz​(x)∑i0k​az,i​∗xi&#xff0c;然后求这些函数的并集中第nnn大的数。 解题思路 我们显然可以得出fz(i)<fz(i1)f_z(i)<f_z(i1)fz​…

ABP前端使用阿里云angular2 UI框架NG-ZORRO分享

一、前言前段时间写博客分享和介绍了阿里云的UI框架NG-ZORRO&#xff08;博客请查看&#xff1a;http://www.cnblogs.com/donaldtdz/p/7892960.html&#xff09;&#xff0c;结合近段时间对.Net开源框架ABP的学习。完成将ABP前端框架替换成阿里云的NG-ZORRO。二、替换说明ABP版…

Prufer序列 生成树定理

Description 在图论中&#xff0c;树的定义是连通且无环的无向图。对于一棵有 nn 个节点且节点从 11 到 nn 编号的树&#xff0c;它的 Prufer 序列是一个唯一的长为 n−2n−2 的标号序列。 Prufer 序列的构造方法&#xff1a;每次删除树中标号最小的叶子节点&#xff08;即度为…

K8S Learning(10)——Pod配置

pod.spec.containers属性是pod配置中最为关键的一项配置。 kubectl explain pod.spec.containersKIND: Pod VERSION: v1 RESOURCE: containers <[]Object> # 数组&#xff0c;代表可以有多个容器 FIELDS:name <string> # 容器名称image <string>…

NOI.AC-积木【堆】

正题 题目链接:http://noi.ac/contest/266/problem/794 题目大意 无限多个1∗21*21∗2的砖块交替着 一个砖块会掉落仅当下方两个砖块都掉落&#xff0c;现在抽出nnn个砖块&#xff0c;求掉落多少个砖块。 解题思路 开一个优先队列&#xff0c;若两个连在一起的就把上面那个…

L3-002 堆栈 树状数组+二分答案

题目详情点击这里 思路&#xff1a;用std::stack来表示题目中说的栈&#xff0c;现在关键问题就是如何找到中位数。 可以用二分答案&#xff0b;树状数组的方法 由于每个元素最大不超过1e5&#xff0c;因此开一个大小为1e5的树状数组来存储不超过x的数有多少个 每次push一个…

K8S Learning(11)——Pod生命周期

一、Pod生命周期 一般将pod对象从创建至终的这段时间范围称为pod的生命周期&#xff0c;它主要包含下面的过程&#xff1a; pod创建过程 运行初始化容器&#xff08;init container&#xff09;过程 运行主容器&#xff08;main container&#xff09; 容器启动后钩子&#…

大规模开发团队如何实现DevOps转型? 来自微软全球开发平台工程团队的实践经验

微软全球开发平台工程团队从敏捷到DevOps的转型2013年11月13日&#xff0c;我们宣布了Visual Studio2013&#xff0c;以及微软研发云Visual Studio Online (VSO)的正式商用。紧接着我们经历了一次长达七小时的服务中断。我们的服务运行在一个“弹性扩展单元”中&#xff0c;为大…

NOI.AC-保镖【贪心,对顶堆】

正题 题目链接:http://noi.ac/contest/266/problem/795 题目大意 nnn个人第iii个巡逻一次aia_iai​秒&#xff0c;休息至少bib_ibi​秒。 要求 任意时刻都有人巡逻在一个人的两次相邻的巡逻直接不能有另一个人巡逻两次。 解题思路 对于性质二我们发现就是在nnn个人里选择最少…

L2-013 红色警报 并查集

题目连接 题解&#xff1a;连通块问题显然要与并查集有关&#xff0c;而且C4比赛极喜欢出与并查集有关的知识。 这道题可以这样做&#xff0c;即我每次去掉一个城市的时候&#xff0c;都对剩余的城市重新建立并查集&#xff0c;然后判断联通块的数量有没有删减&#xff0c;如…

野鸡NOI.AC模拟赛【2019.10.26】

前言 截止至2019.10.2614:222019.10.26\ \ \ \ 14:222019.10.26 14:22 成绩 正题 T1:NOI.AC−T1:NOI.AC-T1:NOI.AC−序列【堆】 https://blog.csdn.net/Mr_wuyongcong/article/details/102755906 T2:NOI.AC−T2:NOI.AC-T2:NOI.AC−积木【堆】 https://blog.csdn.net/Mr_wu…

Golang的CSP很酷?其实.NET也可以轻松完成

CSP&#xff08;Communicating sequential processes&#xff09;这东西我一开始以为很简单&#xff0c;后面差了资料发现它独树一帜&#xff0c;自己是一门语言&#xff0c;也是一套理论。这边我不深入的对它做过多的见解&#xff0c;我怕耽误大家_&#xff0c;大家可以看看wi…

K8S Learning(12)——Pod调度

一、Pod调度 在默认情况下&#xff0c;一个Pod在哪个Node节点上运行&#xff0c;是由Scheduler组件采用相应的算法计算出来的&#xff0c;这个过程是不受人工控制的。但是在实际使用中&#xff0c;这并不满足的需求&#xff0c;因为很多情况下&#xff0c;我们想控制某些Pod到…

jzoj3801-[NOIP2014模拟8.23]骰子【数学期望】

正题 题目链接:https://jzoj.net/senior/#main/show/3801 题目大意 mmm面的骰子是1∼m1\sim m1∼m&#xff0c;然后丢nnn次&#xff0c;求最大值的数学期望。 解题思路 若抛到的数都≤i\leq i≤i那么期望概率就是(1i)n(\frac{1}{i})^n(i1​)n 我们考虑若iii是最大值时概率就是…

L2-016 愿天下有情人都是失散多年的兄妹 CCCC

呵呵。大家都知道五服以内不得通婚&#xff0c;即两个人最近的共同祖先如果在五代以内&#xff08;即本人、父母、祖父母、曾祖父母、高祖父母&#xff09;则不可通婚。本题就请你帮助一对有情人判断一下&#xff0c;他们究竟是否可以成婚&#xff1f; 输入格式&#xff1a; 输…