4

I have a web service interface that abstracts a RabbitMQ server (don't ask me why, I know it's an unnecessary step, but I have to). That is, I poll messages from the queue through a web service call, not directly over amqp.

Consuming via basic.consumer blocks the execution thread till there are messages in the queue. This makes the web service not return.

Code for illustration:

    $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;
4

2 に答える 2

3

私がやりたかったことは、によって達成されbasic.getます。

php-amqlib で:

$channel->basic_get(QUEUE_NAME, true); // the second arg is no_ack.

2 番目の引数は、そのメッセージに対して確認応答が期待されていないことを示しています。つまり、RabbitMQ が自信を持ってメッセージをデキューするために、メッセージに既読の「フラグ」を立てる必要はありません。それを除外する (it = false にする) と、トップ メッセージはポップされません。

なぜこのすべての面倒なのですか?

私は、RabbitMQ コードを http Web サービス内にラップしていました。そして、これは良い考えではありません (少なくとも私の使用例では)。Web サービスが戻り、rabbitmq 接続が終了するときと同様に、(まだ) 確認応答されていないメッセージがキューに再キューイングされます。そのため、http ラッパーを採用する必要がある場合は、rabbitmq 接続の有効期間を http リクエストの有効期間から切り離してください。しかし、私はこれを試しませんでした。

于 2015-09-08T22:51:14.703 に答える