现在的位置: 首页 > 综合 > 正文

RabbitMQ学习(一).NET Client之Send/Receive

2019年10月14日 ⁄ 综合 ⁄ 共 4079字 ⁄ 字号 评论关闭

转载请注明出处:jiq•钦's technical Blog

前言:流行的消息队列主要有ZeroMQ(C++实现),ActiveMQ(Java实现),RabbitMQ(Erlang实现),MSMQ,Kafka,这里可以看到他们的一些评估信息:http://wiki.secondlife.com/wiki/Message_Queue_Evaluation_Notes 更多细节可以自行搜索。

Introduction


下面是RabbitMQ的一些术语:RabbitMQ是一个消息代理,实际上它从消息生产者接收消息,然后将其发送到消息消费者,在这之间可以根据特定规则对消息进行路由,缓冲,以及持久化等。

  • 生产仅仅意味着发送,一个发送消息的程序就称为生产者,比作“P”。

  • 一个队列也可以叫做邮箱,存在于RabbitMQ中,尽管消息会流过RabbitMQ以及你的应用程序,但是它仅仅会被存储在队列中。队列没有任何限制,你想存储多少消息就可以存储多少,多个生产者可以向一个消息队列发送消息,多个消费者也可以尝试从消息队列中接收(取出)消息。队列用下面的图形表示:

  • 消费和接收的意思是相同的,一个消费者就是一个等待接收消息的程序,我们用“C“表示:

记住生产者,消费者以及消息队列(Broker)不一定要存在于同一台机器上,实际上多数情况下它们都不在同一台机器上。

"Hello World"

(using the .NET/C# Client)

在这个部分将会用C#写两个程序,一个是生产者用于发送单个消息,一个是消费者用于接收消息,然后将其打印出来。我们不关注其中涉及到的.NET API的细节,集中注意力在一个简单的”Hello world“的消息上面。

(P) -> [|||] -> (C)

The .NET client library

RabbitMQ speaks AMQP, which is an open, general-purpose protocol for messaging. There are a number of clients
for AMQP in many different languages. We'll use the .NET client provided by RabbitMQ.

Download the client library package, and check its signature as described. Extract it
and copy "RabbitMQ.Client.dll" to your working folder.

You also need to ensure your system can find the C# compiler csc.exe, you may need to add ;C:\WINDOWS\Microsoft.NET\Framework\v3.5 (change
.NET version to fit your installation) to your Path.

有了Rabbit的.NET client库之后,就可以进行下面的代码开发了:

Sending

(P) -> [|||]

我们将会编写一个消息发送者程序Send.cs以及一个消息接收程序Receive.cs,发送者将会连接到RabbitMQ,发送一个消息然后退出。

Send.cs 中,我们需要引入下面命名空间:

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

其中connection对象抽象了socket连接,关注协议的版本协商以及验证,这里我们连接到本地机器的RabbitMQ,所以HostName是localhost,如果我们想要连接到不同机器的broker,那么只需要将它的IP换成这个就可以。

接下来我们创建了channel对象,它几乎完成所有的事情。

要发送一个消息,我们必须要首先声明一个队列,然后才能publish(发送)消息到这个队列。

class Send
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("hello", false, false, false, null);

                string message = "Hello World!";
                var body = Encoding.UTF8.GetBytes(message);

                channel.BasicPublish("", "hello", null, body);
                Console.WriteLine(" [x] Sent {0}", message);
            }
        }
    }
}

声明一个队里是幂等的(idempotent),也就是说仅仅在这个队列不存在的情况加,才会进行队列的创建操作。

消息内容是字节数组,所以在这里你需要进行编码,可以使用任何你喜欢的编码手段。

上面代码跑完之后,connection和channel对象会自动被清理(disposed)。

Here's the whole Send.cs class.

Sending doesn't work!

If this is your first time using RabbitMQ and you don't see the "Sent" message then you may be left scratching your head wondering what could be wrong. Maybe the broker was started without enough free disk space (by default it needs at
least 50 MB free) and is therefore refusing to accept messages. Check the broker logfile to confirm and reduce the limit if necessary. The configuration
file documentation
 will show you how to setdisk_free_limit.

Receiving

消息发送者发送了消息之后,消息接收者将会被RabbitMQ进行消息推送,所以和消息发送者发送一个消息不同,消息接收者需要保持对消息的监听,然后才能收到这个消息进行打印。

[|||] -> (C)

Receive.cs所需要引入的命名空间几乎和Send.cs一样:

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

初始化部分和Send.cs基本一样,也是打开connection和channel,然后声明消费者将要消费的消息队列。

记住接收者也需要先声明队列,因为它可能在发送者之前启动,这个时候队列可能不存在,是不能够进行告诉RabbitMQ进行监听的。

然后创建一个回调函数对象,因为消息会异步到达,所以我们告诉RabbitMQ server将消息队列hello的消息推送给我们的同时,注册了这个回调函数对象,让其可以在消息到达时进行异步调用。

class Receive
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("hello", false, false, false, null);

                var consumer = new QueueingBasicConsumer(channel);
                channel.BasicConsume("hello", true, consumer);

                Console.WriteLine(" [*] Waiting for messages." +
                                         "To exit press CTRL+C");
                while (true)
                {
                    var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                }
            }
        }
    }
}

QueueingBasicConsumer.Queue.Dequeue() 将会阻塞直到当前进程从RabbitMQ server接收到一个新的消息

Here's the whole Receive.cs class.

Putting it all together

你可以通过引用RabbitMQ 的.NET客户端DLL来编译这两个文件,我们使用的是命令行(cmd.exe and csc)来进行编译,你也可以使用Visual
Studio.

$ csc /r:"RabbitMQ.Client.dll" Send.cs
$ csc /r:"RabbitMQ.Client.dll" Receive.cs

Then run the executable

$ Send.exe

then, run the receiver:

$ Receive.exe

消息接收者将会打印消息发送者通过RabbitMQ发送的消息,消息接收者也会保持运行状态,继续等待接收消息。

假如你想要查看队列情况,可以使用rabbitmqctl list_queues命令。

Hello World!

原文:http://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html

抱歉!评论已关闭.