11

I'm required to create a simple queue manager to pass a number from a sender to a consumer. Hello World tutorial provided by RabbitMQ covers almost 70% of it.

But I need to change the queue to not to forever waiting for incoming messages. Or stop waiting after certain amount of messages. I read and tried few solutions from other post, but it doesn't work.

rabbitmq AMQP::consume() - undefined method. there's another method, wait_frame but it is protected.

and other post is in python which I dont understand.

<?php

require_once __DIR__ . '/vendor/autoload.php';
require 'config.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

function recieveQueue($queueName){
    $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

    // try{
    //  $connection->wait_frame(10);
    // }catch(AMQPConnectionException $e){
    //  echo "asdasd";
    // }

    $channel = $connection->channel();

    $channel->queue_declare($queueName, false, false, false, false);

    echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";

    $callback = function($msg) {
        echo " [x] Received ", $msg->body, "\n";

    };

    // $tag = uniqid() . microtime(true);
    // $queue->consume($callback, $flags, $tag);

    $channel->basic_consume($queueName, '', false, true, false, false, $callback);

    // $channel->cancel($tag);

    while(count($channel->callbacks)) {
        $channel->wait();
    }

    echo "\nfinish";
}

recieveQueue('vtiger');

?>
Community
  • 1
  • 1
jedi
  • 151
  • 1
  • 1
  • 9

3 Answers3

12

Modify wait() in while loop:

$timeout = 55;
while(count($channel->callbacks)) {
    $channel->wait(null, false, $timeout);
}
Nick
  • 9,735
  • 7
  • 59
  • 89
  • what does 'null' and 'false' stand for? and may I know if there's a way to stop wait after receive something like 'stop' signal from producer? – jedi Nov 26 '15 at 06:47
  • `public function wait($allowed_methods=null, $non_blocking = false, $timeout = 0)` – Nick Nov 26 '15 at 07:56
  • 1
    Is this a common practice if you run your workers as a cronjob? – Spidfire Dec 07 '16 at 09:58
  • 1
    it would be great if one could just use `channel->wait(null, $nonBlockinge=true);` without having to specify a timeout, but it looks like a non blocking consume on its own never arrived after being requested. https://github.com/pdezwart/php-amqp/issues/55 – Programster Dec 09 '16 at 14:24
  • @mnv Is there a manual page for `wait()` somewhere? You probably just pulled that line from the source code, but an explanation of the function and parameters would help. – Skeets Sep 18 '17 at 21:10
  • I found this example in Internet many time ago and as I see it is not documented – Nick Sep 19 '17 at 10:22
9

wait function works only with sockets, we have to catch the exception:

 $timeout = 5;
    while (count($channel->callbacks)) {
        try{
            $channel->wait(null, false , $timeout);
        }catch(\PhpAmqpLib\Exception\AMQPTimeoutException $e){
            $channel->close();
            $connection->close();
            exit;
        }
    }
0

This is how I did to give signal to the queue to stop consuming incoming messages.

However this may not be a proper way of doing it since it gives an error instead of comes out properly.

Please suggest a better answer if there's one.

    $callback = function($msg) {
        echo " [x] Received ", $msg->body, "\n";

        // if queue recieve 'stop', stop consume anymore messages
        if ($msg->body == 'stop'){
            $channel->basic_cancel($queueName);
        }
    };

    $channel->basic_consume($queueName, '', false, true, false, false, $callback);

    $timeout = 10;
    while(count($channel->callbacks)) {
        // $channel->wait(null, false, $timeout);
        $channel->wait();
    }
tripleee
  • 175,061
  • 34
  • 275
  • 318
jedi
  • 151
  • 1
  • 1
  • 9