一、简介

      RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到邮筒之时,你可以确定的是邮递员先生肯定会把邮件发送到需要接收邮件的人的手里,不会送错的。在这个比喻中,RabbitMQ就是一个邮箱,也可以理解为邮局和邮递员,他们负责把消息发送出去和用于接收信息。

   RabbitMQ和邮局这两者之间的主要区别是它不会处理纸质邮件,取而代之的是接收、存储和发送二进制数据块,也就是我们通常所说的消息。

   RabbitMQ和消息中,通常会使用一些专业术语。

   生产:生产意味着就是发送。 发送消息的程序是一个生产者。下图代表一个消息的生产真:

    

   队列:这里的队列是指一个名称,但是名称所代表的队列实体寄存在RabbitMQ服务器端中。 虽然消息流过RabbitMQ和您的应用程序,但它们只能存储在队列中。 队列只受主机的内存和磁盘的限制,它本质上是一个大的消息缓冲区。 许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。 下图代表一个队列:

   

   消费:消费具有与接收相似的含义。 消费者是一个主要等待接收消息的程序。下图代表消息的消费者:

    

二、(使用 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,以便确保您安装在您的路径中。

    你也可以使用 Net Framework 来完成本实例,只是安装步骤有些不同而已。

    RabbitMQ的客户端类库已经部署到了NuGet上,并且您可以通过NuGet下载和使用。

    本教程假定您正在使用Windows PowerShell。

三、安装

   首先让我们确认您已经有了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

  现在我们已经有了两个项目安装完毕,可以开始写一些代码了。

四、发送消息

         

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

    当前connection连接是一个抽象的套接字连接,为我们负责协议版本的协商和认证等。这里我们连接到本地机器上的消息代理--从此处的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。

五、接收消息

     以上就是我们的消息生产者,我们的消息的消费者是从RabbitMQ拉消息,因此不能像我们的消息发布者那样发布单一消息,我们需要保持我们的消费者程序持续运行,并且监听消息,如果有就获取并且打印出来。

   

Receive.cs文件和Send.cs文件有一些很像的代码需要书写:

       using RabbitMQ.Client;
       using RabbitMQ.Client.Events;
       using System;
       using System.Text;

     消息接收者的设置和消息的发布者一样,我们要打开一个连接和一个通道,并且声明一个从中获取消息的队列,注意这个是和Send.cs文件中的发布者的队列相匹配的。

       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接收事件处理程序所做的。

       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",   noAck: true,    consumer: consumer);

                   Console.WriteLine(" Press [enter] to exit.");
                   Console.ReadLine();
               }
           }
       }

六、把它放在一起

    打开两个端点。

    运行消费者:
 
       cd Receive

       dotnet run

    然后运行生产者

       cd Send

       dotnet Run

    消费者将要打印消息生产者通过RabbitMQ发布的消息。消费者不能间断,必须保持持续运行,等待新消息的到来。当然也可以通过(Ctrl+C 来停止消费者)

好了,终于写完了,其实是我翻译的,有翻译不对的地方请谅解。

原文地址如下:Hello World,第一个事例

RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World的更多相关文章

  1. RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World(转载)

    RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World 一.简介 RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到 ...

  2. RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介(转载)

    RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介 今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. N ...

  3. RabbitMQ系列教程之六:远程过程调用(RPC)(转载)

    RabbitMQ系列教程之六:远程过程调用(RPC) 远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习 ...

  4. RabbitMQ系列教程之五:主题(Topic)(转载)

    RabbitMQ系列教程之五:主题(Topic) (本实例都是使用的Net的客户端,使用C#编写),说明,中文方括号[]表示名词. 在上一个教程中,我们改进了我们的日志记录系统. 没有使用只能够进行虚 ...

  5. RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)(转载)

    RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe) (本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个 ...

  6. RabbitMQ系列教程之四:路由(Routing)(转载)

    RabbitMQ系列教程之四:路由(Routing) (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ...

  7. 2.rabbitmq 系列教程

    rabbitmq系列教程-文章[转] 视频分享: 链接:https://pan.baidu.com/s/1s_Qr2A1o0s8Ru0exK62jqg 提取码:eb68

  8. Unreal Engine 4 系列教程 Part 5:制作简单游戏

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  9. Unreal Engine 4 系列教程 Part 10:制作简单FPS游戏

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

随机推荐

  1. 【HDOJ 1085】数学问题,母函数

    Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  2. 【Android】再来一篇Fragment懒加载(只加载一次哦)

    效果 老规矩,先来看看效果图 没错,我又入坑了,又重新做了个 Gank 客户端,因为之前那个代码写得太烂了,这次有好好的考虑了下架构之类的事,代码应该会更容易读懂了点了,吧.哈哈,再次欢迎来 star ...

  3. Go - 第一个 go 程序 -- helloworld

    创建程序目录 接着上一节的内容,在我们的workspace (D:\Gopher) 里面创建子目录 hello,他的绝对路径为:D:\Gopher\src\github.com\tuo\hello 创 ...

  4. 2017/4/27-Gradle的配置与Spring的下载

    Gradle的配置与Spring的下载 1.Gradle 1) 介绍 Gradle是一个基于Groovy的构建工具,类似Maven,但是比其更加简单轻便.它可以自动化地进行软件构建.测试.发布.部署. ...

  5. bzoj4819 [Sdoi2017]新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的 ...

  6. Linux Bootup Time

    Linux Bootup Time 英文原文地址:http://elinux.org/Boot_Time 1.   简介 启动时间这一话题包括很多子话题,比如启动时间的衡量.启动时间的分析.人为因素分 ...

  7. ie8兼容background-size属性

    满心欢喜地写代码,最后测试兼容性的时候发现Logo图片在IE8下特别大.明显是background-size在ie8一下不兼容. 我懂得,IE8还是个孩子,我就加几句你独有的代码让你兼容吧,司空见惯了 ...

  8. 蓝桥杯-有奖猜谜-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  9. EasyUI开发的驾校管理系统

    开源SmartLife驾校管理系统,地址:https://github.com/SmartOfLife/DriveMgr 1.界面布局是用的ymnets大神的界面,具体参考:http://www.cn ...

  10. WF4.0以上使用代码完整自定义动态生成执行工作流Xaml文件

    给大家分享一下,如何完全使用代码自定义的创建生成工作流文件(用代码创建Xaml文件),并且动态加载运行所生成的工作流. 工作流生成后 在Xaml文件里的主要节点如下: 输入输出参数 <x:Mem ...