How to delay? - php-amqplib

后端 未结 2 1565
遥遥无期
遥遥无期 2020-12-16 23:09

I would like to know how to delay with Amqpphplib.

I used this great coffee script tutorial :

https://github.com/jamescarr/rabbitmq-scheduled-delivery

<
相关标签:
2条回答
  • 2020-12-17 00:03

    If you choose amqp interop based transport you won't need to dig into details at all. Only a few things to do:

    Install enqueue/amqp-lib (btw you can use other transports based on amqp ext and a great bunny lib) transport and enqueue/amqp-tools.

    composer require enqueue/amqp-lib enqueue/amqp-tools
    

    Create amqp context, add a delay strategy and send delayed messages:

    <?php
    use Enqueue\AmqpTools\RabbitMqDlxDelayStrategy;
    use Enqueue\AmqpBunny\AmqpConnectionFactory;
    
    $context = (new AmqpConnectionFactory('amqp://'))->createContext();
    $context->setDelayStrategy(new RabbitMqDlxDelayStrategy())
    
    $queue = $context->createQueue('foo');
    $context->declareQueue($queue);
    
    $message = $context->createMessage('Hello world!');
    
    $context->createProducer()
        ->setDeliveryDelay(5000) // 5 sec
        ->send($queue, $message)
    ;
    

    By the way, this not this only strategy available. there is one based on RabbitMQ delay plugin. It could be used the same way.

    0 讨论(0)
  • 2020-12-17 00:11

    I just wrote a simplified working version for php:

    /////// simplified ///////
    
    // include the AMQPlib Classes || use an autoloader
    
    // queue/exchange names
    $queueRightNow = 'right.now.queue';
    $exchangeRightNow = 'right.now.exchange';
    $queueDelayed5sec = 'delayed.five.seconds.queue';
    $exchangeDelayed5sec = 'delayed.five.seconds.exchange';
    
    $delay = 5; // delay in seconds
    
    // create connection
    $AMQPConnection = new \PhpAmqpLib\Connection\AMQPConnection('localhost',5672,'guest','guest');
    
    // create a channel
    $channel = $AMQPConnection->channel();
    
    // create the right.now.queue, the exchange for that queue and bind them together
    $channel->queue_declare($queueRightNow);
    $channel->exchange_declare($exchangeRightNow, 'direct');
    $channel->queue_bind($queueRightNow, $exchangeRightNow);
    
    // now create the delayed queue and the exchange
    $channel->queue_declare(
            $queueDelayed5sec,
            false,
            false,
            false,
            true,
            true,
            array(
                'x-message-ttl' => array('I', $delay*1000),   // delay in seconds to milliseconds
                "x-expires" => array("I", $delay*1000+1000),
                'x-dead-letter-exchange' => array('S', $exchangeRightNow) // after message expiration in delay queue, move message to the right.now.queue
            )
    );
    $channel->exchange_declare($exchangeDelayed5sec, 'direct');
    $channel->queue_bind($queueDelayed5sec, $exchangeDelayed5sec);
    
    // now create a message und publish it to the delayed exchange
    $msg = new \PhpAmqpLib\Message\AMQPMessage(
        time(),
        array(
            'delivery_mode' => 2
        )
    );
    $channel->basic_publish($msg,$exchangeDelayed5sec);
    
    
    // consume the delayed message
    $consumeCallback = function(\PhpAmqpLib\Message\AMQPMessage $msg) {
        $messagePublishedAt = $msg->body;
        echo 'seconds between publishing and consuming: '
            . (time()-$messagePublishedAt) . PHP_EOL;
    };
    $channel->basic_consume($queueRightNow, '', false, true, false, false, $consumeCallback);
    
    // start consuming
    while (count($channel->callbacks) > 0) {
        $channel->wait();
    }
    
    0 讨论(0)
提交回复
热议问题