/// <summary> /// 接受消息,使用委托进行处理,使用QueueingBasicConsumer方法(已过时) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="receiveMethod"></param> public ExeResEdm Receive <T>(ReceiveMessageDelegate <T> receiveMethod) { ExeResEdm exeResEdm = new ExeResEdm() { }; try { using (var channel = this.GetConnection().CreateModel()) { //是否使用路由 if (!string.IsNullOrWhiteSpace(this.RabbitConfig.Exchange)) { //声明路由 // channel.ExchangeDeclare(this.RabbitConfig.Exchange, this.RabbitConfig.ExchangeType.ToString(), this.RabbitConfig.DurableQueue); //声明队列且与交换机绑定 channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); channel.QueueBind(this.RabbitConfig.QueueName, this.RabbitConfig.Exchange, this.RabbitConfig.RoutingKey); } else { channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); } //输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息 channel.BasicQos(0, 1, false); ///告诉RabbitMQ同一时间给一个消息给消费者 //在队列上定义一个消费者 var consumer = new QueueingBasicConsumer(channel); //消费队列,并设置应答模式为程序主动应答 channel.BasicConsume(this.RabbitConfig.QueueName, false, consumer); while (true) { //阻塞函数,获取队列中的消息 ProcessingResultsEnum processingResult = ProcessingResultsEnum.Retry; ulong deliveryTag = 0; try { //获取信息 var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); deliveryTag = ea.DeliveryTag; byte[] bytes = ea.Body; string str = Encoding.UTF8.GetString(bytes); T v = SerializerHelper.DeserializeToObject <T>(str); receiveMethod(v); processingResult = ProcessingResultsEnum.Accept; //处理成功 } catch //(Exception ex) { processingResult = ProcessingResultsEnum.Reject; //系统无法处理的错误 } finally { System.Threading.Thread.Sleep(100);//暂停0.1秒,防止CPU爆满的问题 switch (processingResult) { case ProcessingResultsEnum.Accept: //回复确认处理成功 channel.BasicAck(deliveryTag, false); break; case ProcessingResultsEnum.Retry: //发生错误了,但是还可以重新提交给队列重新分配 channel.BasicNack(deliveryTag, false, true); break; case ProcessingResultsEnum.Reject: //发生严重错误,无法继续进行,这种情况应该写日志或者是发送消息通知管理员 channel.BasicNack(deliveryTag, false, false); //写日志 break; } } } } } catch (Exception ex) { exeResEdm.ErrCode = 1; exeResEdm.ExBody = ex; exeResEdm.Module = "RabbitMQHelper.Receive方法"; LogCom.WriteExceptToFile(ex, "RabbitMQHelper.Receive"); } return(exeResEdm); }
/// <summary> /// 接受消息,使用委托进行处理,使用 EventingBasicConsumer 方法,3.6.12版本服务器接收出错 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="receiveMethod"></param> public void Receive2 <T>(ReceiveMessageDelegate <T> receiveMethod) { try { using (var channel = this.GetConnection().CreateModel()) { //是否使用路由 if (!string.IsNullOrWhiteSpace(this.RabbitConfig.Exchange)) { //声明路由 // channel.ExchangeDeclare(this.RabbitConfig.Exchange, this.RabbitConfig.ExchangeType.ToString(), this.RabbitConfig.DurableQueue); //声明队列且与交换机绑定 channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); // channel.QueueBind(this.RabbitConfig.QueueName, this.RabbitConfig.Exchange, this.RabbitConfig.RoutingKey); } else { channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); } //输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息 channel.BasicQos(0, 1, false); ///告诉RabbitMQ同一时间给一个消息给消费者 //在队列上定义一个消费者 var consumer = new EventingBasicConsumer(channel); //消费队列,并设置应答模式为程序主动应答,oAck设置false,告诉broker,发送消息之后,消息暂时不要删除,等消费者处理完成再说 channel.BasicConsume(this.RabbitConfig.QueueName, false, consumer); consumer.Received += (model, ea) => { ProcessingResultsEnum processingResult = ProcessingResultsEnum.Retry; ulong deliveryTag = 0; try { //获取信息 deliveryTag = ea.DeliveryTag; byte[] bytes = ea.Body; string str = Encoding.UTF8.GetString(bytes); T v = SerializerHelper.DeserializeToObject <T>(str); receiveMethod(v); processingResult = ProcessingResultsEnum.Accept; //处理成功 // channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); //处理完成,告诉Broker可以服务端可以删除消息,分配新的消息过来 } catch (Exception ex) { LogCom.WriteExceptToFile(ex, "RabbitMQHelper.Receive"); processingResult = ProcessingResultsEnum.Reject; //系统无法处理的错误 } finally { System.Threading.Thread.Sleep(100);//暂停0.1秒,防止CPU爆满的问题 switch (processingResult) { case ProcessingResultsEnum.Accept: //回复确认处理成功 channel.BasicAck(deliveryTag, false); break; case ProcessingResultsEnum.Retry: //发生错误了,但是还可以重新提交给队列重新分配 channel.BasicNack(deliveryTag, false, true); break; case ProcessingResultsEnum.Reject: //发生严重错误,无法继续进行,这种情况应该写日志或者是发送消息通知管理员 channel.BasicNack(deliveryTag, false, false); //写日志 break; } } }; } } catch (Exception ex) { LogCom.WriteExceptToFile(ex, "RabbitMQHelper.Receive"); } }
/// <summary> /// 接受消息,使用委托进行处理 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="receiveMethod"></param> public void Receive <T>(ReceiveMessageDelegate <T> receiveMethod) { try { using (var channel = this.GetConnection().CreateModel()) { //是否使用路由 if (!string.IsNullOrWhiteSpace(this.RabbitConfig.Exchange)) { //声明路由 channel.ExchangeDeclare(this.RabbitConfig.Exchange, this.RabbitConfig.ExchangeType.ToString(), this.RabbitConfig.DurableQueue); //声明队列且与交换机绑定 channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); channel.QueueBind(this.RabbitConfig.QueueName, this.RabbitConfig.Exchange, this.RabbitConfig.RoutingKey); } else { channel.QueueDeclare(this.RabbitConfig.QueueName, this.RabbitConfig.DurableQueue, false, false, null); } //输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息 channel.BasicQos(0, 1, false); ///告诉RabbitMQ同一时间给一个消息给消费者 //在队列上定义一个消费者 var consumer = new QueueingBasicConsumer(channel); //消费队列,并设置应答模式为程序主动应答 channel.BasicConsume(this.RabbitConfig.QueueName, false, consumer); while (true) { //阻塞函数,获取队列中的消息 ProcessingResultsEnum processingResult = ProcessingResultsEnum.Retry; ulong deliveryTag = 0; try { Thread.Sleep(500);//暂停0.5秒,防止CPU爆满的问题 //获取信息 var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); deliveryTag = ea.DeliveryTag; byte[] bytes = ea.Body; string str = Encoding.UTF8.GetString(bytes); T v = JsonConvert.DeserializeObject <T>(str); receiveMethod(v); processingResult = ProcessingResultsEnum.Accept; //处理成功 } catch (Exception) { processingResult = ProcessingResultsEnum.Reject; //系统无法处理的错误 } finally { switch (processingResult) { case ProcessingResultsEnum.Accept: //回复确认处理成功 channel.BasicAck(deliveryTag, false); break; case ProcessingResultsEnum.Retry: //发生错误了,但是还可以重新提交给队列重新分配 channel.BasicNack(deliveryTag, false, true); break; case ProcessingResultsEnum.Reject: //发生严重错误,无法继续进行,这种情况应该写日志或者是发送消息通知管理员 channel.BasicNack(deliveryTag, false, false); //写日志 break; } } } } } catch (Exception) { throw; } }