Rabbitmq使用单个同步调用检索多条消息

Rabbitmq使用单个同步调用检索多条消息,rabbitmq,synchronous,Rabbitmq,Synchronous,有没有一种方法可以使用一个同步调用来接收多条消息 当我知道队列中有N条消息(N可能是小于10的小值)时,我应该能够执行类似channel.basic_get(String queue,boolean autoAck,int numberofMsg)的操作。我不想向服务器发出多个请求。RabbitMQ的basic.get不支持多条消息。检索多条消息的首选方法是使用将消息推送到客户端的方法,以避免多次往返确认是异步的,因此客户端不会等待服务器响应basic.consume还有一个好处,即在客户端断开

有没有一种方法可以使用一个同步调用来接收多条消息


当我知道队列中有N条消息(N可能是小于10的小值)时,我应该能够执行类似channel.basic_get(String queue,boolean autoAck,int numberofMsg)的操作。我不想向服务器发出多个请求。

RabbitMQ的
basic.get
不支持多条消息。检索多条消息的首选方法是使用将消息推送到客户端的方法,以避免多次往返<代码>确认是异步的,因此客户端不会等待服务器响应
basic.consume
还有一个好处,即在客户端断开连接时,允许RabbitMQ重新传递消息,而这是
basic.get
无法做到的。也可以将
no ack
设置为
true


设置
basic.qos
prefetch count
将设置随时推送到客户端的消息数。如果客户端没有消息等待(将立即返回),客户端库往往会使用可选的超时来阻塞

您可以使用
QueueingConsumer
接口的
QueueingConsumer
实现,该接口允许您在一个请求中检索多条消息

 QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
 channel.basicConsume(plugin.getQueueName(), false, queueingConsumer);

 for(int i = 0; i < 10; i++){
    QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery(100);//read timeout in ms
    if(delivery == null){
      break;
    }
 }
QueueingConsumer QueueingConsumer=新的QueueingConsumer(通道);
channel.basicConsume(plugin.getQueueName(),false,queueingConsumer);
对于(int i=0;i<10;i++){
QueueingConsumer.Delivery Delivery=QueueingConsumer.nextDelivery(100);//读取超时(毫秒)
如果(传递==null){
打破
}
}

首先声明封装模型的QueueingBasicConsumer()的实例。
从模型执行model.BasicConsume(QueueName,false,consumer)
然后实现一个循环,循环来自队列的消息,然后队列将处理
下一行-consumer.Queue.Dequeue()方法-等待从队列接收消息。
然后将字节数组转换为字符串并显示它。
Model.BasicAck()-从队列中释放消息以接收下一条消息
然后服务器端可以开始等待下一条消息:

  public string GetMessagesByQueue(string QueueName)
    {
        var consumer = new QueueingBasicConsumer(_model);
        _model.BasicConsume(QueueName, false, consumer);

        string message = string.Empty;

        while (Enabled)
        {
            //Get next message
            var deliveryArgs = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

            //Serialize message
             message = Encoding.Default.GetString(deliveryArgs.Body);
                _model.BasicAck(deliveryArgs.DeliveryTag, false);
        }
        return message;
    }

这不是一个优雅的解决方案,也不能解决多次调用的问题,但您可以使用MessageCount方法。例如:

  bool noAck = false;
  var messageCount = channel.MessageCount("hello");
  BasicGetResult result = null;
  if (messageCount == 0)
  {
      // No messages available
  }
  else
  {
      while (messageCount > 0)
      {
          result = channel.BasicGet("hello", noAck);
          var message = Encoding.UTF8.GetString(result.Body);
          //process message .....
          messageCount = channel.MessageCount("hello");
      }

如今,这是一个不受欢迎的解决方案。这不是对所问问题的回答。在某些情况下(例如,出于安全考虑),无法从MessageBroker触发连接,而只能从安全区域触发到不太安全的区域。在这种情况下,这仍然缺少对所问问题的答案。AMQP或RabbitMQ可能已发生更改,允许同步调用在其间几年内获取多条消息。RabbitMQ的连接来自客户端->兔子。消息的发布通过此现有连接进行。使用
basic.get
basic.consume
不会改变建立连接的方式。这是关于使用未发布的消息。这是否意味着由使用者建立连接,然后保持打开状态以便RabbitMQ回调工作?在限制防火墙规则的情况下,在某些情况下可能不存在这种情况。。从这个意义上讲,age of basic.get或basic.consume的使用确实会改变连接的处理方式。无论连接上使用的命令是什么,客户端都会创建连接,无论是使用连接还是发布连接。由于连接上的AMQP消息,回调由客户端库处理。