///消息生产端
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); } }