C# 操作rabbitmq(二)

接着上一篇继续分析rabbitmq的使用,此篇介绍rabbitmq的publish/Subcribe

一、Exchange
rabbitmq建议消息的producer不要直接的把消息发送给queue,而是把消息发送给Exchange。
Exchange一边接收来自producer的消息,一边将消息push给queue。
C# 操作rabbitmq(二)_第1张图片

rabbitmq提供了四种exchange type:

  • direct :第三篇
  • topic :第四篇
  • headers :很少使用,rabbitmq官网没有给出例子
    此类型的exchange和以上三个都不一样,其路由的规则是根据header来判断,其中的header就是以下方法的arguments参数:

    Dictionary aHeader = new Dictionary();
    aHeader.Add("format", "pdf");
    aHeader.Add("type", "report");
    aHeader.Add("x-match", "all");
    channel.QueueBind(queue: "queue.A",
                exchange: "agreements",
                routingKey: string.Empty,
                arguments: aHeader);
    

    其中的x-match为特殊的header,可以为all则表示要匹配所有的header,如果为any则表示只要匹配其中的一个header即可。

    var factory = new ConnectionFactory() { HostName = "localhost" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
        // Headers类型的exchange, 名称 agreements
        channel.ExchangeDeclare(exchange: "agreements",
                        type: ExchangeType.Headers,
                        durable: true,
                        autoDelete: false,
                        arguments: null);
    
        // 创建queue.A队列
        channel.QueueDeclare(queue: "queue.A", durable: true, exclusive: false, autoDelete: false, arguments: null);
    
        /*发布者*/
        string message1 = "hello world";
        var body = Encoding.UTF8.GetBytes(message1);
        var properties = channel.CreateBasicProperties();
        properties.Persistent = true;
        Dictionary mHeader1 = new Dictionary();
        mHeader1.Add("format", "pdf");
        mHeader1.Add("type", "report");
        properties.Headers = mHeader1;
    
        //queue.A 的binding (format=pdf, type=report, x-match=all)
        channel.BasicPublish(exchange: "agreements",
                        routingKey: string.Empty,
                        basicProperties: properties,
                        body: body);
    
        //接收者
        Dictionary aHeader = new Dictionary();
        aHeader.Add("format", "pdf");
        aHeader.Add("type", "report");
        aHeader.Add("x-match", "all");
        channel.QueueBind(queue: "queue.A",
                    exchange: "agreements",
                    routingKey: string.Empty,
                    arguments: aHeader);
    }
    
  • fanout : 将接收到消息广播给它所知道的queue

    channel.ExchangeDeclare("logs", "fanout"); //声明一个fanout类型的exchange ,名称为logs
    
    var message = GetMessage(args);
    var body = Encoding.UTF8.GetBytes(message);
    channel.BasicPublish(exchange: "logs",
                 routingKey: "",
                 basicProperties: null,
                 body: body);
    

我们知道,无论什么时候连接rabbitmq需要一个全新的空的queue,因此可以用获取一个随机的queue名称,更多关于queue属性请参考 guide on queue

//create a non-durable, exclusive, autodelete queue with a generated name:
var queueName = channel.QueueDeclare().QueueName;

//将queue与exchange绑定
channel.QueueBind(queue: queueName,
              exchange: "logs",
              routingKey: "");

这里写图片描述

C# 操作rabbitmq(二)_第2张图片

publish

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

class EmitLog
{
    public static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using(var connection = factory.CreateConnection())
        using(var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "logs", type: "fanout");

            var message = GetMessage(args);
            var body = Encoding.UTF8.GetBytes(message);
            channel.BasicPublish(exchange: "logs",
                                 routingKey: "",
                                 basicProperties: null,
                                 body: body);
            Console.WriteLine(" [x] Sent {0}", message);
        }

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

    private static string GetMessage(string[] args)
    {
        return ((args.Length > 0)
               ? string.Join(" ", args)
               : "info: Hello World!");
    }
}

Subcribe

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

class ReceiveLogs
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using(var connection = factory.CreateConnection())
        using(var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "logs", type: "fanout");

            var queueName = channel.QueueDeclare().QueueName;
            channel.QueueBind(queue: queueName,
                              exchange: "logs",
                              routingKey: "");

            Console.WriteLine(" [*] Waiting for logs.");

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                Console.WriteLine(" [x] {0}", message);
            };
            channel.BasicConsume(queue: queueName,
                                 autoAck: true,
                                 consumer: consumer);

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

你可能感兴趣的:(RabbitMQ)