У меня есть интерфейс веб-сервиса, который абстрагирует сервер RabbitMQ (не спрашивайте меня, почему, я знаю, что это ненужный шаг, но я должен). То есть, я просматриваю сообщения из очереди через вызов веб-службы, а не напрямую по amqp
.
Потребление через basic.consumer
блокирует поток выполнения до тех пор, пока в очереди не basic.consumer
сообщения. Это заставляет веб-службу не возвращаться.
Код для иллюстрации:
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare(QUEUE_NAME, false, true, false, false);
$ret = array('body' => '');
$callback = function($msg) use ($channel, &$ret) {
$ret['body'] = $msg->body;
/*
Here I would basic.cancel the consumer if there were no messages in the queue
*/
};
$channel->basic_consume(QUEUE_NAME, 'tag', false, true, false, false, $callback);
if (count($channel->callbacks)) {
$channel->wait(); // blocks here...
}
return $ret;
Если вы хотите получить размер очереди, вы можете вызвать queue_declare
с php-amqlib, второй аргумент возврата - количество сообщений в очереди.
list($queue, $messageCount, $consumerCount) = $channel->queue_declare(QUEUE_NAME, true);
Важно, чтобы аргумент $ passive был равен true, когда вы вызываете метод queue_declare()
То, что я хотел сделать, достигается basic.get
.
В php-amqlib:
$channel->basic_get(QUEUE_NAME, true);//the second arg is no_ack
$channel->basic_get(QUEUE_NAME, true);//the second arg is no_ack
.
Тем не менее, я до сих пор не понимаю, что делает второй аргумент, но исключая его (имея его = false), приводит к тому, что не появляется верхнее сообщение. В любом случае, решил.
Как я узнал (и другие, упомянутые ниже), второй аргумент отмечает, что для этого сообщения не ожидается подтверждения. То есть вам не нужно "указывать" сообщение, как прочитано для RabbitMQ, чтобы уверенно удалить его.
Я обертывал код RabbitMQ внутри веб-службы http. И это не очень хорошая идея (по крайней мере, для моего случая использования). Как и при возврате веб-службы, и, таким образом, соединение rabbitmq прекращается, сообщение non (еще) подтверждено обратно в очередь. Итак, если вам нужно принять http-обертку, убедитесь, что вы изолируете время жизни соединения rabbitmq от HTTP-запроса lieftime. Однако я этого не делал.