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