03. 扇形交换机 一对多

场景 : 1.主办方 发布一个活动 

   2.客户a 收到信息预约

  3. 发送邮件给客户 (或者短信通知)

 

代码:

生产者: 
public void Method3()
{
  

//创建RabbitMQ工厂
ConnectionFactory factory = new ConnectionFactory()
{
HostName = "127.0.0.1",
Port = 5672,
UserName = "guest",
Password = "guest",
VirtualHost = "/"
};


//创建 连接
using (IConnection connection = factory.CreateConnection())
{


//创建 通道
//IModel createModel = connection.CreateModel();
var channel = connection.CreateModel();


//------定义交换机



/*
exchange:交换器的名称
type:交换器的类型
durable:是否持久化,true代表持久化。(持久化会将交换器存入磁盘)
autoDelete:是否自动删除,true表示自动删除。(当该交换器上绑定的最后一个队列/交换器解除绑定后,该交换器自动删除)
internal:是否是内置的,true表示内置交换器。(生产者无法直接发消息给内置交换器,只能通过其他交换器路由到该交换器)
argument:其他一些结构化的参数



1.2 交换器类型
1.2.1 fanout
把所有消息路由到与该交换器绑定的队列
1.2.2 direct
路由时需要BindingKey和RoutingKey完全匹配
1.2.3 topic
路由到BindingKey和RoutingKey相匹配的队列
RoutingKey和BindingKey为以“.”分隔的字符串
BindingKey中可以存在“*”(匹配一个单词),“#”(匹配多个单词,也可以是0个)


*/


string exchangeStr = "create_PlanInfo_fanout";


channel.ExchangeDeclare(
exchange: exchangeStr, //交换器的名称
type: "fanout", //交换器的类型
durable:true
);


//创建发送到队里信息里内容

string planinfoJson = JsonConvert.SerializeObject(planinfo);
byte[] bobyByte = Encoding.UTF8.GetBytes(planinfoJson);


//发送消息内容
IBasicProperties properties = channel.CreateBasicProperties();
properties.Persistent = true;// 这里也可以设置消息持久化


//channel.ConfirmSelect();


channel.BasicPublish(
exchange: exchangeStr,
routingKey: "",
basicProperties: properties,
body: bobyByte
);


Console.WriteLine($"主办方:发布一个计划{planinfo.PlanNo} --{planinfo.PlanName} 创建成功!!!");


//logger.LogInformation("主办方:预约的计划创建成功!!!");
}

 
  }
消费者客户
 public void Method3()
 {
     //创建连接
     var connection = factory.CreateConnection();
     //创建通道
     var channel = connection.CreateModel();

     //定义队列
     string queueName = channel.QueueDeclare().QueueName;

     var exchangeSty = "create_PlanInfo_fanout";


     // exchange:交换器的名称
     //type:交换器的类型
     //durable:是否持久化,true代表持久化。(持久化会将交换器存入磁盘)
     //     autoDelete:是否自动删除,true表示自动删除。(当该交换器上绑定的最后一个队列 / 交换器解除绑定后,该交换器自动删除)
     //     internal:是否是内置的,true表示内置交换器。(生产者无法直接发消息给内置交换器,只能通过其他交换器路由到该交换器)
     //     argument:其他一些结构化的参数

     // 定义交换机
     channel.ExchangeDeclare(
         exchange: exchangeSty,
         type: "fanout",
          durable: true
         );

     //交换机和队列绑定
     channel.QueueBind(
         queue: queueName,
         exchange: exchangeSty,
         routingKey: ""

         );

     //创建 事件基本消费者
     var consumer = new EventingBasicConsumer(channel);
     //接收到消息事件
     consumer.Received += (model, ea) =>
     {
         var message = Encoding.UTF8.GetString(ea.Body.ToArray());
         Console.WriteLine($"客户消费者 预定: {message}");

         {
             //.....业务逻辑代码
         }

         //手动确认消费
         channel.BasicAck(ea.DeliveryTag, true);

     };


     //消费能力   Qos(防止多个消费者,能力不一致,导致的系统质量问题。
     // 每一次一个消费者只成功消费一个)
     channel.BasicQos(0, 1, false);  //这里设定消费能力  是1个

     channel.BasicConsume(queue: queueName,
                         autoAck: false,//自动消息确认 ,如果设置为false,会导致消息重复消费 ,那么就需要手动确认
                         consumer: consumer
                         );
 }

邮件:
 public void Method3()
 {
     //1. 创建工厂

     //创建连接
     var connection = factory.CreateConnection();
     //创建通道
     var channel = connection.CreateModel();



     // exchange:交换器的名称
     //type:交换器的类型
     //durable:是否持久化,true代表持久化。(持久化会将交换器存入磁盘)
     //     autoDelete:是否自动删除,true表示自动删除。(当该交换器上绑定的最后一个队列 / 交换器解除绑定后,该交换器自动删除)
     //     internal:是否是内置的,true表示内置交换器。(生产者无法直接发消息给内置交换器,只能通过其他交换器路由到该交换器)
     //     argument:其他一些结构化的参数

     var exchangeSty = "create_PlanInfo_fanout";
     // 定义交换机
     channel.ExchangeDeclare(
         exchange: exchangeSty,
         type: "fanout",
           durable: true
         );


     //定义队列
     string queueName = channel.QueueDeclare().QueueName;

     //交换机和队列绑定
     channel.QueueBind(
         queue: queueName,
         exchange: exchangeSty,
         routingKey: ""

         );

     //创建 事件基本消费者
     var consumer = new EventingBasicConsumer(channel);
     //接收到消息事件
     consumer.Received += (model, ea) =>
     {
         var message = Encoding.UTF8.GetString(ea.Body.ToArray());
         Console.WriteLine($"邮件消费者根据 预定: {message}  发送邮件");

         {
             //.....业务逻辑代码
         }


         //手动确认消费
         channel.BasicAck(ea.DeliveryTag, true);

     };


     //消费能力   Qos(防止多个消费者,能力不一致,导致的系统质量问题。
     // 每一次一个消费者只成功消费一个)
     channel.BasicQos(0, 1, false);  //这里设定消费能力强点  是1个

     channel.BasicConsume(queue: queueName,
                         autoAck: false,//自动消息确认 ,如果设置为false,会导致消息重复消费 ,那么就需要手动确认
                         consumer: consumer
                         );
 }

结果:

 

posted @ 2025-05-29 13:43  逆流而下  阅读(10)  评论(0)    收藏  举报