Net中使用 RabbitMq | Return

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

消息不可达

项目需要先启动消费端,再启动生产端

生产端

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

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端口  
            AutomaticRecoveryEnabled = true,//网络故障自动连接恢复
        };
        /// <summary>
        /// 路由名称
        /// </summary>
        const string ExchangeName = "exchange999";
        const string routingKey = "routing.return999";
        //队列名称
        //const string QueueName = "queue010";
        static void Main(string[] args)
        {
            using (IConnection conn = rabbitMqFactory.CreateConnection()) //创建一个连接
            {
                using (IModel channel = conn.CreateModel()) //创建一个Channel
                {                   
                    IBasicProperties props = channel.CreateBasicProperties();
                    props.DeliveryMode = 2; //1:非持久化 2:持续久化 (即:当值为2的时候,我们一个消息发送到服务器上之后,如果消息还没有被消费者消费,服务器重启了之后,这条消息依然存在)
                    props.Persistent = true;
                    props.ContentEncoding = "UTF-8"; //注意要大写
                    //props.Expiration = "250000"; //消息过期时间为25秒

                   
                    //这个事件就是用来监听我们一些不可达的消息的(比如)
                    EventHandler<BasicReturnEventArgs> evreturn = new EventHandler<BasicReturnEventArgs>((o, b) => {
                        Console.WriteLine(b.ReplyCode); //消息失败的code
                        Console.WriteLine(b.ReplyText);
                        Console.WriteLine(Encoding.UTF8.GetString(b.Body)); //失败消息的内容
                    });
                    channel.BasicReturn += evreturn;

                    //我们也可以设定自定义属性,把自定义的属性放到Headers中进行发送
                    var dir = new Dictionary<string, object>();
                    dir.Add("name", "张三");//特别要注意,字符串传递过去的时候是实际是以byte[]数组的形式传递过去的
                    dir.Add("age", 25);
                    props.Headers = dir;

                    for (int i = 0; i < 5; i++)
                    {
                        props.MessageId = Guid.NewGuid().ToString("N"); //设定这条消息的MessageId(每条消息的MessageId都是唯一的)

                        string msg = "你好,这是我的第" + i + "条消息;时间:" + DateTime.Now.ToString("yyyy:MM:dd");
                        var msgBody = Encoding.UTF8.GetBytes(msg); //发送的消息必须是二进制的
                        channel.BasicPublish(exchange: ExchangeName, routingKey: routingKey, mandatory:true, basicProperties: props, body: msgBody);
                    }
                    Console.ReadKey();
                }
            }
        }
    }
}

消费端

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
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 = "exchange999";

        //队列名称
        const string QueueName = "queue999";
        const string routingKey = "routing-return"; //这里routingkey与消费端的routingkey不保持一致的原因就是要测试生产端的消息不可达,测试不可达所产生的事件调用
        static void Main(string[] args)
        {
            using (IConnection conn = rabbitMqFactory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {                
                    channel.ExchangeDeclare(ExchangeName, "topic", durable: true, autoDelete: false, arguments: null);                   
                    channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
                    channel.QueueBind(QueueName, ExchangeName, routingKey: routingKey); 
                    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);//告诉broker同一时间只处理一个消息

                    EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

                    while (true)
                    {
                        consumer.Received += (model, ea) =>
                        {
                           
                            var msgBody = Encoding.UTF8.GetString(ea.Body);
                            Console.WriteLine(string.Format("接收时间:{0},消息内容:{1}", DateTime.Now.ToString("HH:mm:ss"), msgBody));

                        //处理完成,告诉Broker可以服务端可以删除消息,分配新的消息过来
                        channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                        };
                        //noAck设置false,告诉broker,发送消息之后,消息暂时不要删除,等消费者处理完成再说
                        channel.BasicConsume(QueueName, autoAck: false, consumer: consumer);
                    }
                }
            }
        }
    }
}

猜你喜欢

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