RabbitMQ学习笔记(一) Hello World

原文: RabbitMQ学习笔记(一) Hello World

RabbitMQ是做什么的?#

RabbitMQ可以类比现实生活中的邮政服务。

现实中邮件服务处理的是邮件,发件人写好信件投入邮箱,邮递员收取信件存入邮局,邮局根据信件地址,分配邮递员投递信件到指定地点。

RabbitMQ与邮政服务的主要区别是RabbitMQ处理的是消息(二进制数据块), 即消息的接收、存储、分发。

RabbitMQ中的主要概念#

消息生产者(producer)#

发送消息的程序

消息消费者(Consumer)#

等待接收消息的程序

消息队列#

RabbitMQ中的消息队列,就相当于邮政服务中的邮箱,所有通过RabbitMQ和你的应用程序发送接收的消息都存储在消息队列中,它是一个巨大的消息缓存,它的大小仅受服务器内存和硬盘空间的限制。

多个消息生产者可以通过同一个消息队列发送消息,多个消息消费者也可以通过同一个消息队列接收消息。

消息的生产者、消费者、消息队列不需要一定放置在同一个服务器中,现实中的大部分应用场景也不会允许他们放置在同一服务器中

第一个Hello World程序#

这里我们创建2个控制台程序,一个负责发送简单的 Hello World消息,一个负责输出接收到的消息,并在控制台打印。

流程图如下,P为生产者,C为消费者,中间的红色块是消息队列

创建程序#

使用.NET Core的命令行工具,创建2个控制台程序,一个命名为Send, 另外一个命名为Receive。

1
2
3
dotnet new console –name Send
 
dotnet new console –name Receive

安装RabbitMQ客户端程序集#

使用.NET Core的命令行工具,分别为2个控制台程序添加RabbitMQ客户端程序集

dotnet add package RabbitMQ.Client

dotnet restore

编写消息发送程序#

首先引入一些命名空间

1
2
3
4
5
using System;
 
using RabbitMQ.Client;
 
using System.Text;

然后在修改Main方法添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var factory = new ConnectionFactory() { HostName = "localhost" };
 
         using ( var connection = factory.CreateConnection())
 
         {
 
             using ( var channel = connection.CreateModel())
 
             {
 
                
 
             }
 
         }

connection对象抽象出了一个Socket连接,并负责RabbitMQ所使用的协议版本的验证和协商。

这里连接的是本地的RabbitMQ实例,所以使用的localhost作为主机名,如果需要连接其他服务器的RabbitMQ实例,只需要将主机名变更为对应服务器的ip地址即可。

然后我们需要创建一个channel对象,大部分的消息处理有关的api都是在channel对象中。

接下来,为了发送消息,我们需要创建一个消息队列,然后向这个消息队列中发布消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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();
 
     }
 
}

Channel对象的QueueDeclare方法是用来声明一个消息队列的,这个方法是等幂的,即只要当该消息队列不存在的时候才创建他,如果已经存在,就直接返回之前创建的对象。

RabbitMQ中传递的消息是二进制数据,所以需要将传递的文本转换成二进制数据。

这样消息发送程序就完成了。

编写接收消息程序#

前面我们做的发送程序运行一次只发送一条消息,与发送程序不同,接收消息程序需要监听接收到的所有消息,并打印。

首先我们引入需要使用的命名空间

1
2
3
4
5
6
7
using RabbitMQ.Client;
 
using RabbitMQ.Client.Events;
 
using System;
 
using System.Text;

初始的设置代码和发送程序一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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 );
 
                
 
             }
 
         }
 
     }

这里还要重复声明一次消息队列的原因是,你不能保证在消息接收程序启动时,消息队列一定存在(即消息接收程序的启动早于发送消息程序)。

由于消息的推送是异步的,所以这里我们需要使用事件来捕捉消息,并打印在控制台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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();
 
         }

运行程序#

在消息发送程序和消息接收程序目录下,使用.NET Core命令行工具启动2个项目

dotnet run

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/11904980.html