/// <summary> /// 根据对列名称获取对列模型 /// </summary> /// <param name="queueName"></param> /// <returns></returns> public static RabbitMessageQueueOptions ReaderByQueue(string queueName) { List <RabbitMessageQueueOptions> messageQueueOptionsList = ReaderAll(); RabbitMessageQueueOptions entity = messageQueueOptionsList.Where(q => q.QueueName == queueName).FirstOrDefault(); return(entity); }
/// <summary> /// 加载所有对列配置文件 /// </summary> /// <returns></returns> private static List <RabbitMessageQueueOptions> ReaderAll() { List <RabbitMessageQueueOptions> messageQueueOptionsList = new List <RabbitMessageQueueOptions>(); List <ExchangeConfigOptions> exchangeConfigOptionsList = RabbitMQContext.Config.ExchangeConfig; if (exchangeConfigOptionsList == null || exchangeConfigOptionsList.Count <= 0) { throw new ArgumentNullException("ReaderAll:加载配置文件为空"); } foreach (ExchangeConfigOptions configOptions in exchangeConfigOptionsList) { foreach (var queueItem in configOptions.Queues) { RabbitMessageQueueOptions queueOptions = new RabbitMessageQueueOptions() { ExchangeName = configOptions.ExchangeName, ExchangeType = configOptions.ExchangeType, Persistent = configOptions.Persistent, QueueName = queueItem.QueueName, RoutingKeys = queueItem.RoutingKeys, }; messageQueueOptionsList.Add(queueOptions); } } return(messageQueueOptionsList); }
/// <summary> /// 接收消息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="queue">队列名称</param> /// <param name="isProperties"></param> /// <param name="handler">消费处理</param> /// <param name="isDeadLetter"></param> public void Subscribe <T>(Action <T> handler) where T : class { //每次消费的消息数 _channel.BasicQos(0, 1, false); RabbitMessageQueueOptions queueOptions = RabbitQueueOptionsUtil.ReaderByQueue(_queueName); _channel.ExchangeDeclare(queueOptions.ExchangeName, ExchangeType.Direct); _channel.QueueDeclare(_queueName, true, false, false, null); _channel.QueueBind(_queueName, queueOptions.ExchangeName, queueOptions.RoutingKeys); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (model, ea) => { var body = ea.Body; var msgStr = body.StreamToStr(); var msg = SerializerJson.DeserializeObject <T>(msgStr); string messageId = ea.BasicProperties.MessageId;//消息Id try { handler(msg); } catch (Exception ex) { Console.WriteLine($"队列:{_queueName},MessageId:{messageId}", ex); } finally { _channel.BasicAck(ea.DeliveryTag, false); } }; _channel.BasicConsume(_queueName, false, consumer); }
/// <summary> /// 发布消息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity">对像实例</param> /// <param name="isCreateQueue">是否创建对列</param> public void Publish <T>(T entity, bool isCreateQueue = false) where T : class { //获取当前队列的特性 var queueAttrInfo = AttributeUtil.GetRabbitMQAttribute <T>(); if (queueAttrInfo.IsNullOrEmpty()) { throw new ArgumentException("RabbitMQAttribute未定义"); } var queueName = queueAttrInfo.QueueName; var body = entity.SerializeObjectToBytes(); RabbitMessageQueueOptions queueOptions = RabbitQueueOptionsUtil.ReaderByQueue(queueName); var exchangeType = queueOptions.ExchangeType; var exchange = queueOptions.ExchangeName; var routingKey = queueOptions.RoutingKeys; if (isCreateQueue) { Publish(exchangeType, exchange, routingKey, body, queueName); } else { Publish(exchangeType, exchange, routingKey, body); } }
private RabbitMessageQueueOptions CreateOptions() { var options = new RabbitMessageQueueOptions(); ConfigurationBinder.Bind(_configuration, "RabbitMessageQueueOptions", options); _configureOptions?.Invoke(options); return(options); }
/// <summary> /// 发布消息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity">对像实例</param> /// <param name="queueName">对列名称</param> /// <param name="isCreateQueue">是否创建对列</param> public void Publish <T>(T entity, string queueName, bool isCreateQueue = false) where T : class { byte[] body = entity.SerializeObjectToBytes(); RabbitMessageQueueOptions queueOptions = RabbitQueueOptionsUtil.ReaderByQueue(queueName); var exchangeType = queueOptions.ExchangeType; var exchange = queueOptions.ExchangeName; var routingKey = queueOptions.RoutingKeys; if (isCreateQueue) { Publish(exchangeType, exchange, routingKey, body, queueName); } else { Publish(exchangeType, exchange, routingKey, body); } }
/// <summary> /// 接收消息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="queue">队列名称</param> /// <param name="isProperties"></param> /// <param name="handler">消费处理</param> /// <param name="isDeadLetter"></param> public void SubscribeRetry <T>(Action <T> handler) where T : class { //每次消费的消息数 _channel.BasicQos(0, 1, false); RabbitMessageQueueOptions queueOptions = RabbitQueueOptionsUtil.ReaderByQueue(_queueName); _channel.ExchangeDeclare(queueOptions.ExchangeName, queueOptions.ExchangeType, queueOptions.Persistent); _channel.QueueDeclare(_queueName, true, false, false, null); _channel.QueueBind(_queueName, queueOptions.ExchangeName, queueOptions.RoutingKeys); var retryDic = new Dictionary <string, object> { { "x-dead-letter-exchange", queueOptions.ExchangeName }, { "x-dead-letter-routing-key", queueOptions.RoutingKeys } }; _channel.ExchangeDeclare(queueOptions.ExchangeName.GetRetrySuffixName(), queueOptions.ExchangeType); _channel.QueueDeclare(_queueName.GetRetrySuffixName(), true, false, false, retryDic); _channel.QueueBind(_queueName.GetRetrySuffixName(), queueOptions.ExchangeName.GetRetrySuffixName(), queueOptions.RoutingKeys.GetRetrySuffixName()); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (model, ea) => { bool canAck = false; //应答结果 int retryCount = 0; //第几次重试 string messageId = ea.BasicProperties.MessageId; IDictionary <string, object> headers = ea.BasicProperties.Headers; if (headers != null && headers.ContainsKey(RetryCountKeyName)) { retryCount = (int)headers[RetryCountKeyName]; retryCount++; Console.WriteLine($"队列:{_queueName},MessageId:{messageId},第:{retryCount}次重试开始!!!"); //Logger.Info($"队列:{_queueName},MessageId:{messageId},第:{retryCount}次重试开始!!!"); } try { var body = ea.Body; var msgStr = body.StreamToStr(); var msg = SerializerJson.DeserializeObject <T>(msgStr); handler(msg); canAck = true; } catch (Exception ex) { Console.WriteLine($"队列:{_queueName},MessageId:{messageId},第:{retryCount}次消费发生异常:", ex); //Logger.Error($"队列:{_queueName},MessageId:{messageId},第:{retryCount}次消费发生异常:", ex); if (CanRetry(retryCount)) { RetryHandler(retryCount, queueOptions.ExchangeName.GetRetrySuffixName(), queueOptions.RoutingKeys.GetRetrySuffixName(), ea); canAck = true; } else { canAck = false; } } //处理应答 AnswerHandler(canAck, ea); }; _channel.BasicConsume(_queueName, false, consumer); }