##介绍
RabbitMQ是一个消息代理。它的核心原理非常简单:接收和发送消息。你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,RabbitMQ是一个邮箱、邮局、邮递员。RabbitMQ和邮局的主要区别是,它处理的不是纸,而是接收、存储和发送二进制的数据——消息。
一般提到RabbitMQ和消息,都用到一些专有名词。
- **生产(Producing)**意思就是发送。发送消息的程序就是一个生产者(producer)。我们一般用”P”来表示:
![Producing](http://www.rabbitmq.com/img/tutorials/producer.png)
- **队列(queue)**就是邮箱的名称。消息通过你的应用程序和RabbitMQ进行传输,它们能够只存储在一个队列(queue)中。队列(queue)没有任何限制,你要存储多少消息都可以——基本上是一个无限的缓冲。多个生产者(producers)能够把消息发送给同一个队列,同样,多个消费者(consumers)也能够从一个队列(queue)中获取数据。队列可以用下图标识:
![Queue](http://www.rabbitmq.com/img/tutorials/queue.png)
- 消费(Consuming)和获取消息是一样的意思。一个消费者(consumer)就是一个等待获取消息的程序。我们把它画作”C”:
![Consuming](http://www.rabbitmq.com/img/tutorials/consumer.png)
> **注意:**一般生产者,消费者和代理不必部署在同一台机子上。
##Hello World 示例
###简介
我们的“Hello world”不会很复杂——仅仅发送一个消息,然后获取它并输出到屏幕。这样以来我们需要两个程序,一个用作发送消息,另一个接受消息并打印消息内容。
大体的设计如下所示:
![](http://www.rabbitmq.com/img/tutorials/python-one.png)
###Sending 发送端
![](http://www.rabbitmq.com/img/tutorials/sending.png)
我们会创建一个**Send.cs**,来实现,连接**RabbitMQ**,发送一条简单的信息,然后退出。
首先在**Send.cs**中,我们需要添加必要的命名空间
```
using System;
using RabbitMQ.Client;
using System.Text;
```
创建类
```
class Send
{
public static void Main()
{
...
}
}
```
接下来,创建与RabbitMQ Server 的连接
```
class Send
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
...
}
}
}
}
```
这里创建了一个Socket连接,负责协议版本协商和身份验证等等,这里由于连接的是本地机子,所以取值`localhost`。
接下来,创建一个channel(通道),大多数任务都是在这里完成的。
要发送消息,我们必须首先定义一个**queue(队列)**,然后我们才成把消息发送给**queue**
```
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();
}
}
```
queue 的定义具有幂等性(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相等),因此定义的queue已经存在,不会重复定义,且不能修改。
当上面的代码执行完,channel 和connection会disposed(处理掉,释放掉)。
###Receiving 接收端
接收端会从 RabbitMQ server 拉取消息,因此接收端 要监听消息,然后打印输出
![](http://www.rabbitmq.com/img/tutorials/receiving.png)
与Send.cs代码一样,引用必要的命名空间
```
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
```
同Sender 接收端一样,我们要打来 一个connection和channel,定义一个queue用来从中获取消息。
```
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);
...
}
}
}
}
```
>NOTE:也许你已经发现,我们在接收端也定义了hello队列。这是为了确保,如果接收端先启动的时候,队列已经存在。
接下来,我们就要告诉服务器来交付消息。由于推送消息是一个异步操作,因此我们使用回调函数,这里我们使用`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",
noAck: true,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}
```
##演示
首先我们要将 RabbitMQ.NET Client 程序集和上面的代码文件放到一起
接下来,我们可以打开` Visual Studio 命令提示工具`,`cd`到上面代码说在文件夹,运行下面的命令来编译代码。
```
$ csc /r:"RabbitMQ.Client.dll" Send.cs
$ csc /r:"RabbitMQ.Client.dll" Receive.cs
```
我们会在文件所在目录下,看到生成的Send.exe 和Receive.exe
我们运行连个程序。
先运行
`
$ Send.exe
`
会看到提示 发送的信息
接下来运行
`
$ Receive.exe
`
我们会看到 显示我们之前发送的消息。
接收端会获取发送端通过RabbitMQ 发送的消息。接收端会一直执行,接收发送端发送的消息。
如果这个时候,我们再另外打开Send.exe,我们会看到接收端显示新的消息。
如果我们想查看队列的信息,我们可以使用下面的命令
```
rabbitmqctl list_queues.
```