Net中使用 RabbitMq | Direct ExChange 直连模式(路由模式)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fanbin168/article/details/89320738

RabbitMQ提供了四种Exchange:direct, topic, fanout, header 
header模式在实际使用中较少,本文只对前三种模式进行比较。

Direct ExChange属于直连模式,直连模式就是 Exchange 通过 指定的RoutingKey 将 消息转发到与之绑定的Queue中

注:可以这样理解:生产者想发送一条消息到指定的Queue队列中,首先这条消息会Exchange接收到,因为Exchange与queue是进行了绑定,这个绑定指定了RoutingKey(路由名称),这时候Exchange就会通过这个路由名称,来找到指定的Queue,然后将消息保存到Queue中 这就是直连模式

注:当一个Exchange与Queue进行绑定的时候,不是一定要指定RoutingKey的,比如Fanout 模式下就不需要指定RoutingKey

废话不多,看下面Demo代码

创建连个项目 一个生产者,一个消费者,在这两个项目中都安装RabbitMQ.Client

PM>Install-Package RabbitMQ.Client -Version 5.1.0

ProducterApp 生产者

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading.Tasks;

namespace ProducterApp
{
    class Program
    {
        /// 连接配置
        /// </summary>
        private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory() //创建一个工厂连接对象
        {
            HostName = "192.168.31.30",
            UserName = "admin",
            Password = "admin",           
            VirtualHost="/vhost001", //如果不设置,虚拟主机名称路径默认为 /
            Port = 5672, //注意:5672 --是client端通信口   15672 -- 是管理界面ui端口           
        };
        /// <summary>
        /// 路由名称
        /// </summary>
        const string ExchangeName = "exchange001";


        //队列名称
        const string QueueName = "queue001";
        static void Main(string[] args)
        {
            using (IConnection conn = rabbitMqFactory.CreateConnection()) //创建一个连接
            {
               
                using (IModel channel = conn.CreateModel()) //创建一个Channel
                {
                    //生产者在发送消息的时候一般情况下都要指定一个Exchange,如果不指定,则是默认的default
                    //default的路由规则是:一般情况下都要指定一个Exchange类型,如果不指定,直接写一个空字符串,它就会按照你的RoutingKey 然后去Queues中找你对应名称Queue,如果能找到就才能路由到这个Queue

                    //Exchange的Type类型有:direct,topic, fanout,headers
                    //direct:所有发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue;当消费者要消费这个Queue中的消息都会时候它要求消费者的RoutingKey与生产者的RoutingKey完全匹配
                    //topic:所有发送到Topic Exchange的消息都会转发到所有关心的RoutingKey



                    //durable是Exchange(交换机)的属性,它表示是否需要持久化,为true则为持久化。false表示不需要持久化

                    //autoDelete:它是Exchange(交换机)的属性,它的值有true和false两种
                    //为true 则表示当最后一个绑定到Exchange(交换机)上的Queue(队列)删除后,就自动删除该Exchange
                    //这段话也很好理解,假如Exchange(交换机)上绑定了三个Queue(队列),当这个三个Queue(队列)都被删除的时候这个Exchange(交换机)将会被自动删除

                    //arguments:它是扩展参数,用于扩展AMQP协议自制定化的使用
                    channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null); //声明一个Exchange(交换机)

                    //QueueName:消息队列名称
                    //durable:是否缓存
                    //autoDelete:如果没有与任何交换机进行绑定的时候是否删这个Queue,为true则删除,false则不删除
                    channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);//声明一个队列

                    string routingKey = "routing-"+QueueName;//这个routingKey的值可以随便你自己设置,一般情况下直接设置为QueueName的值就行
                    channel.QueueBind(QueueName, ExchangeName, routingKey: routingKey);

                    
                    var props = channel.CreateBasicProperties();
                    props.Persistent = true;

                    for (int i = 0; i < 5; i++)
                    {
                        //System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
                        string msg = "你好,RabbitMq,这是我的第" + i + "条消息;时间:" + DateTime.Now.ToString();
                        var msgBody = Encoding.UTF8.GetBytes(msg); //发送的消息必须是二进制的
                        channel.BasicPublish(exchange: ExchangeName, routingKey: routingKey, basicProperties: props, body: msgBody);
                    }                   
                }
            }
        }
    }
}

CustomerApp消费者

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

namespace CustomerApp
{
    class Program
    {
        /// <summary>
        /// 连接配置
        /// </summary>
        private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory()
        {
            HostName = "192.168.31.30",
            UserName = "admin",
            Password = "admin",
            Port = 5672,
            VirtualHost = "/vhost001",
        };
        /// <summary>
        /// 路由名称
        /// </summary>
        const string ExchangeName = "exchange001";
        //队列名称
        const string QueueName = "queue001";
        static void Main(string[] args)
        {
            using (IConnection conn = rabbitMqFactory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null);
                    channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);

                    string routingKey = "routing-" + QueueName;
                    channel.QueueBind(QueueName, ExchangeName, routingKey: routingKey);
                    while (true)
                    {
                        //System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
                        BasicGetResult msgResponse = channel.BasicGet(QueueName, autoAck: false);
                        if (msgResponse != null)
                        {
                            var msgBody = Encoding.UTF8.GetString(msgResponse.Body);
                            Console.WriteLine(string.Format("接收时间:{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody));
                        }                      
                    }
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Fanbin168/article/details/89320738