/// <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); } }
/// <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); }