///消息生产端
public class MqProduction { #region Fileds #endregion #region Constructorsc #endregion #region Methons public static async Task<bool> MessageSend(object data, string queueName) { try { #region //1.1.实例化连接工厂 var factory = new ConnectionFactory() { HostName = Configurations.GetValue("RabbitMQ.HostName").ToString(), UserName = Configurations.GetValue("RabbitMQ.UserName").ToString(), Password = Configurations.GetValue("RabbitMQ.Password").ToString(), RequestedHeartbeat = TimeSpan.FromSeconds(30) }; //2. 建立连接 using (var connection = factory.CreateConnection()) { //3. 创建信道 using (var channel = connection.CreateModel()) { #region 通过指定durable:true,并指定Persistent=true,来告知RabbitMQ将消息持久化。 生产端设置后 消费端也要设置 ///************注意如果 要改成消息持久化 那么queue 的名字不能是以前的 因为以前已经可能有服务占用了 ************/// //4. 申明队列(指定durable:true,告知rabbitmq对消息进行持久化) channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); //将消息标记为持久性 - 将IBasic Properties.SetPersistent设置为true var properties = channel.CreateBasicProperties(); properties.Persistent = true; //5. 构建byte消息数据包 string message = data.ToString(); var body = Encoding.UTF8.GetBytes(message); //6. 发送数据包(指定basicProperties) channel.BasicPublish(exchange: "", routingKey: queueName, basicProperties: properties, body: body); //ReferenceCounting.Count = ReferenceCounting.Count + 1; //Console.WriteLine($" {ReferenceCounting.Count} [x] Sent {message}"); #endregion } } return true; #endregion } catch (Exception ex) { LoggerHelper.Error(ex.Message); LoggerHelper.Error(ex.ToString()); throw new AggregateException(ex.Message); } } #endregion #region Utilities #endregion }
  
///消息消费端
public class MqConsumption { #region Fileds #endregion #region Constructors #endregion #region Methons public static Task ConsumptionQueue() { try { //1.实例化连接工厂 var factory = new ConnectionFactory() { HostName = Configurations.GetValue("RabbitMQ.HostName").ToString(), UserName = Configurations.GetValue("RabbitMQ.UserName").ToString(), Password = Configurations.GetValue("RabbitMQ.Password").ToString(), RequestedHeartbeat = TimeSpan.FromSeconds(30) }; //2. 建立连接 using (var connection = factory.CreateConnection()) { //3. 创建信道 using (var channel = connection.CreateModel()) { #region 添加的有消息确认的代码 //4. 申明队列 channel.QueueDeclare(queue: Configurations.GetValue("RabbitMQ.QueueName").ToString(), durable: true, exclusive: false, autoDelete: false, arguments: null); //设置prefetchCount : 1来告知RabbitMQ,在未收到消费端的消息确认时,不再分发消息,也就确保了当消费端处于忙碌状态时 channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false); //5. 构造消费者实例 var consumer = new EventingBasicConsumer(channel); //6. 绑定消息接收后的事件委托 consumer.Received += (model, ea) => { var message = Encoding.UTF8.GetString(ea.Body.ToArray()); Task.Run(async delegate { //await ordersService.PlaceAnOrders(message, true, "XP"); }); // 7. 发送消息确认信号(手动消息确认) channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); }; //8. 启动消费者 //autoAck:true;自动进行消息确认,当消费端接收到消息后,就自动发送ack信号,不管消息是否正确处理完毕 //autoAck:false;关闭自动消息确认,通过调用BasicAck方法手动进行消息确认 channel.BasicConsume(queue: Configurations.GetValue("RabbitMQ.QueueName").ToString(), autoAck: false, consumer: consumer); Console.ReadLine(); //卡住线程 相当于一个长链接 #endregion } } return Task.CompletedTask; } catch (Exception ex) { LoggerHelper.Error(ex.Message); LoggerHelper.Error(ex.ToString()); throw new AggregateException(ex.Message); } } #endregion #region Utilities #endregion }

 消息消费端案例

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

            //app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            var t = Task.Run(async delegate
            {
                QueueConsumption queueConsumption = new QueueConsumption();
                await queueConsumption.MqConsumptionQueue();
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

 

 public Task MqConsumptionQueue()
        {
            try
            {
                //1.实例化连接工厂
                var factory = new ConnectionFactory()
                {
                    HostName = Configurations.GetValue("RabbitMQ.HostName").ToString(),
                    UserName = Configurations.GetValue("RabbitMQ.UserName").ToString(),
                    Password = Configurations.GetValue("RabbitMQ.Password").ToString(),
                    RequestedHeartbeat = TimeSpan.FromSeconds(30)
                };
                //2. 建立连接
                using (var connection = factory.CreateConnection())
                {
                    //3. 创建信道
                    using (var channel = connection.CreateModel())
                    {
                        #region 添加的有消息确认的代码
                        //4. 申明队列
                        channel.QueueDeclare(queue: Configurations.GetValue("RabbitMQ.QueueName").ToString(), durable: true, exclusive: false, autoDelete: false, arguments: null);
                        //设置prefetchCount : 1来告知RabbitMQ,在未收到消费端的消息确认时,不再分发消息,也就确保了当消费端处于忙碌状态时
                        channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);

                        //5. 构造消费者实例
                        var consumer = new EventingBasicConsumer(channel);
                        //6. 绑定消息接收后的事件委托
                        consumer.Received += (model, ea) =>
                        {
                            var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                            try
                            {
                                //Task.Run(async delegate { await _allCreateService.MqAllCreate(message); });
                                var state = _allCreateService.MqAllCreate(message).Result;

                                // 7. 发送消息确认信号(手动消息确认)
                                channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                            }
                            catch (Exception ex)
                            {
                                //true 将消费分给下一个 消费者 false不进入队列
                                channel.BasicReject(deliveryTag: ea.DeliveryTag, false);
                            }
                        };
                        //8. 启动消费者
                        //autoAck:true;自动进行消息确认,当消费端接收到消息后,就自动发送ack信号,不管消息是否正确处理完毕
                        //autoAck:false;关闭自动消息确认,通过调用BasicAck方法手动进行消息确认
                        channel.BasicConsume(queue: Configurations.GetValue("RabbitMQ.QueueName").ToString(), autoAck: false, consumer: consumer);
                        Console.ReadLine(); //卡住线程
                        #endregion
                    }
                }
                return Task.CompletedTask;
            }
            catch (Exception ex)
            {
                LoggerHelper.Error(ex.Message);
                LoggerHelper.Error(ex.ToString());
                throw new AggregateException(ex.Message);
            }
        }

 

posted on 2021-11-11 12:14  白码一号  阅读(429)  评论(0编辑  收藏  举报