C#之RabbitMQ系列(二)--Hello World

生产者–消费者模式

上一篇讨论了如何搭建我们的开发环境,无论使用哪种语言,服务的部署肯定都是相同的。

摘自官网:RabbitMQ is a message broker. In essence, it accepts messages from producers, and delivers them to consumers. In-between, it can route, buffer, and persist the messages according to rules you give it.(译文:兔子就是消息代理,本质上,它接受来自producers的消息然后分发给consumers,在此过程中,它能够根据你定制的规则来路由缓存持久化消息)。
本文开始将基于生产者-消费者模式创建第一个项目,hello world,是否感觉很亲切呢!

既然是生产者-消费者模式,那么显然意味着我们会有生产者和消费者两套程序。生产者负责生产message并推送给queue,而消费者从queue中拉取消息进行处理。


生产者

首先我们需要创建一个控制台应用程序,生产者,即消息发送方,我们创建一个类Send.cs,当然,如果你愿意,也可以叫Producer.cs或者F**k.cs等等。
还记否,上一篇我们已经下载好了驱动,即RabbitMQ.Client.dll,现在只要在此项目中引用即可。

代码中这样引用即可(哎,官网就是这么详细,稍有常识的猿直接跳过)

using System;
using System.Text;
using RabbitMQ.Client;
  • 1
  • 2
  • 3

接下来就可以和RabbitMQ Server创建连接了:

class Send
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };//创建代理服务器实例。注意:HostName为Rabbit Server所在服务器的ip或域名,如果服务装在本机,则为localhost,默认端口5672
        using (var connection = factory.CreateConnection())//创建socket连接
        {
            using (var channel = connection.CreateModel())//channel中包含几乎所有的api来供我们操作queue
            {
                ...
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

很简单的对不对,接下来给出Send.cs的完整代码,为了方便理解,注释我会写在代码中:

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())
        {
            //声明queue
            channel.QueueDeclare(queue: "hello",//队列名
                                 durable: false,//是否持久化
                                 exclusive: false,//true:排他性,该队列仅对首次申明它的连接可见,并在连接断开时自动删除
                                 autoDelete: false,//true:如果该队列没有任何订阅的消费者的话,该队列会被自动删除
                                 arguments: null);//如果安装了队列优先级插件则可以设置优先级

            string message = "Hello World!";//待发送的消息
            var body = Encoding.UTF8.GetBytes(message);

            channel.BasicPublish(exchange: "",//exchange名称
                                 routingKey: "hello",//如果存在exchange,则消息被发送到名称为hello的queue的客户端
                                 basicProperties: null,
                                 body: body);//消息体
            Console.WriteLine(" [x] Sent {0}", message);
        }

        Console.WriteLine(" Press [enter] to exit.");
        Console.ReadLine();
    }
}
  • 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

好的,接下来启动程序,我们的消息就被推送到了Rabbit Server上的queue中,等待客户端的连接,也就是等待消费者拉取。如下图:


消费者

这次重新创建控制台应用程序,类名为Receive.cs,同理,你可以用自己舒服的单词去命名。

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",//指定发送消息的queue,和生产者的queue匹配
                                 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,//和tcp协议的ack一样,为false则服务端必须在收到客户端的回执(ack)后才能删除本条消息
                                 consumer: consumer);

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }
}
  • 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

这段代码是不是和Send很相似呢,没错,在创建连接和声明queue上没有区别!
运行程序,效果如下:

哪怕你的Send程序已关闭,但只要运行过且成功发送了,queue就会一直保存消息,直到客户端连接,这些消息才会一股脑儿发送给消费者。
你可以这样实验,在bin中debug目录下启动Send.exe,连续3次,然后再运行客户端,就会收到3条消息,如下图:

至此,我们的Hello World已经成功跑起。这个小demo当然不是仅仅用来say hello的,更多的用意是帮助我理解兔子的基本原理,提供一种高并发情形下的解决方案。相信以后公司商城发展壮大时能够用到!!!

期待下一篇咯!


猜你喜欢

转载自blog.csdn.net/andrewniu/article/details/80240980