• RabbitMQ (七) 订阅者模式之主题模式 ( topic )


    主题模式和路由模式很像

    路由模式是精确匹配

    主题模式是模糊匹配

     

    依然先通过管理后台添加一个交换机.

    生产者

    复制代码
        public class Producer
        {
    
            private const string ExchangeName = "test_exchange_topic";
    
            public static void Send()
            {
                //获取一个连接
                IConnection connection = ConnectionHelper.GetConnection();
    
                //从连接中获取一个通道
                IModel channel = connection.CreateModel();
    
                //声明交换机
                //channel.ExchangeDeclare(ExchangeName, "topic", false, false, null);
    
                //每次只向消费者发送一条消息,消费者使用后,手动确认后,才会发送另外一条
                channel.BasicQos(0, 1, false);
                
                string msg = "hello world ";
    
                //发送消息,只发送到路由键为"product.delete" 或者 "product.#"的队列.
                //# 匹配一个或多个
                //* 匹配一个
                //上限为 255 个字节
                channel.BasicPublish(ExchangeName, "product.delete", null, Encoding.Default.GetBytes(msg));
                Console.WriteLine($"send {msg}");
    
                channel.Close();
                connection.Close();
            }
        }
    复制代码

    消费者1

    复制代码
        public class Consumer1
        {
            private const string QueueName = "test_exchange1_queue";
            private const string ExchangeName = "test_exchange_topic";
    
            public static void Receive()
            {
                //获取连接
                RabbitMQ.Client.IConnection connection = ConnectionHelper.GetConnection();
    
                //创建通道
                RabbitMQ.Client.IModel channel = connection.CreateModel();
    
                //声明队列
                channel.QueueDeclare(QueueName, false, false, false, null);
    
                //将队列绑定到交换机上
                channel.QueueBind(QueueName, ExchangeName, "product.add", null);
                channel.QueueBind(QueueName, ExchangeName, "product.update", null);
                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
    
                //注册事件
                consumer.Received += (s, e) =>
                {
                    byte[] bytes = e.Body;
                    string str = Encoding.Default.GetString(bytes);
                    Console.WriteLine("consumer1 : " + str);
                    channel.BasicAck(e.DeliveryTag, false);//手动应答
                };
    
                //监听队列
                //bool autoAck = true;//自动确认,一旦mq将消息分发给了消费者,就会从内存中删除该消息
                bool autoAck = false;//手动应答.
                channel.BasicConsume(QueueName, autoAck, "", false, false, null, consumer);
            }
        }
    复制代码

    消费者2

    复制代码
        public class Consumer2
        {
            private const string QueueName = "test_exchange2_queue";
            private const string ExchangeName = "test_exchange_topic";
            public static void Receive()
            {
                //获取连接
                RabbitMQ.Client.IConnection connection = ConnectionHelper.GetConnection();
    
                //创建通道
                RabbitMQ.Client.IModel channel = connection.CreateModel();
    
                //声明队列
                channel.QueueDeclare(QueueName, false, false, false, null);
                
                //将队列绑定到交换机上
                channel.QueueBind(QueueName, ExchangeName, "product.#", null);         //添加消费者
                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
    
                //注册事件
                consumer.Received += (s, e) =>
                {
                    byte[] bytes = e.Body;
                    string str = Encoding.Default.GetString(bytes);
                    Console.WriteLine("         consumer2 : " + str);
                    channel.BasicAck(e.DeliveryTag, false);//手动应答
                };
    
                //监听队列
                //bool autoAck = true;//自动确认,一旦mq将消息分发给了消费者,就会从内存中删除该消息
                bool autoAck = false;//手动应答.
                channel.BasicConsume(QueueName, autoAck, "", false, false, null, consumer);
            }
        }
    复制代码

    运行结果:

     

    由于消费者1的路由键只有 "product.add" 和 "product.update" ,不包含"product.delete",

    而消费者2的路由键是"product.#",可以模糊匹配上"product.delete",

    所以交换机只会把消息转发到消费者2声明的队列中.

  • 相关阅读:
    mysql(自动添加系统时间)timestamp类型字段的CURRENT_TIMESTAMP与ON UPDATE CURRENT_TIMESTAMP属性
    五分钟带你了解啥是JWT
    Eureka和ZooKeeper的区别
    SpringCloud系列之: Eureka注册中心原理及其搭建
    总结下微服务中降级、熔断,以及springcloud中Hystrix的原理以及实现
    POJ1113:Wall (凸包算法学习)
    Java-Graphics类的绘图方法实现
    java.awt.event.MouseEvent鼠标事件的定义和使用 以及 Java Swing-JTextArea的使用
    java swing JDialog 和 java.util.concurrent的使用
    Java-Swing的JFrame的一些插件使用详解
  • 原文地址:https://www.cnblogs.com/liujunjun/p/14140924.html
Copyright © 2020-2023  润新知