Example #1
0
 /**
  * @param string $title
  * @param boolean $durable
  * @param boolean $autoDelete
  * @param array $arguments
  * @throws Exception
  */
 public function createQueue($title, $durable = false, $autoDelete = false, $arguments = null)
 {
     if (!$this->channel) {
         throw new Exception("Channel didn't created");
     }
     $this->channel->queue_declare($title, false, $durable, false, $autoDelete, false, $arguments);
     $this->channel->basic_qos(null, 1, null);
 }
Example #2
0
 /**
  * Infinite loop: Listens for messages from the queue and sends them to the callback.
  *
  * @param callback $callback
  */
 public function listen($callback)
 {
     $this->channel->basic_qos(null, 1, null);
     $this->channel->basic_consume(self::QUEUE_NAME, '', false, true, false, false, $callback);
     while ($this->channel->callbacks) {
         $this->channel->wait();
     }
 }
 /**
  * Creates (if not yet created) and returns an AMQP channel.
  *
  * @return \PhpAmqpLib\Channel\AMQPChannel
  */
 protected function getChannel()
 {
     if (null === $this->channel) {
         $this->channel = $this->connection->channel();
         $this->channel->queue_declare($this->queueName, false, false, false, false);
         $this->channel->basic_qos(null, 1, null);
     }
     return $this->channel;
 }
Example #4
0
 /**
  * @return AMQPChannel
  */
 public function getAmqpChannel()
 {
     if ($this->amqp_channel) {
         return $this->amqp_channel;
     }
     $this->amqp_channel = $this->connection->getAmqpConnection()->channel();
     $this->amqp_channel->queue_declare($this->queue_config['queue_name'], false, $is_durable = true, false, false);
     $this->amqp_channel->basic_qos(null, $this->queue_config['fetch_count'], null);
     return $this->amqp_channel;
 }
 /**
  * @param AMQPStreamConnection $connection
  * @param EventBusInterface $eventBus
  * @param DeserializerLocatorInterface $deserializerLocator
  * @param StringLiteral $consumerTag
  * @param StringLiteral $exchangeName
  * @param StringLiteral $queueName
  * @param int $delay
  */
 public function __construct(AMQPStreamConnection $connection, EventBusInterface $eventBus, DeserializerLocatorInterface $deserializerLocator, StringLiteral $consumerTag, StringLiteral $exchangeName, StringLiteral $queueName, $delay = 0)
 {
     $this->connection = $connection;
     $this->channel = $connection->channel();
     $this->channel->basic_qos(0, 4, true);
     $this->eventBus = $eventBus;
     $this->deserializerLocator = $deserializerLocator;
     $this->queueName = $queueName;
     $this->consumerTag = $consumerTag;
     $this->exchangeName = $exchangeName;
     $this->delay = $delay;
     $this->declareQueue();
     $this->registerConsumeCallback();
 }
Example #6
0
 public function work($maxMessages = null, $timeOut = null)
 {
     $callback = function (AMQPMessage $message) {
         $this->handle($message);
     };
     $this->channel->basic_qos(null, 1, null);
     $this->channel->basic_consume($this->queue, '', false, false, false, false, $callback);
     // Loop infinitely (or up to $count) to execute tasks
     while (count($this->channel->callbacks) && (is_null($maxMessages) || $maxMessages > 0)) {
         $this->channel->wait();
         if (!is_null($maxMessages)) {
             $maxMessages--;
         }
     }
 }
Example #7
0
 /**
  * Starts to listen a queue for incoming messages.
  * @param string $queueName The AMQP queue
  * @param array  $handlers  Array of handler class instances
  * @return bool
  */
 public function listenToQueue($queueName, array $handlers)
 {
     $this->queueName = $queueName;
     /* Look for handlers */
     $handlersMap = array();
     foreach ($handlers as $handlerClassPath) {
         if (!class_exists($handlerClassPath)) {
             $handlerClassPath = "RabbitManager\\Handlers\\{$handlerClassPath}";
             if (!class_exists($handlerClassPath)) {
                 $this->logger->addError("Class {$handlerClassPath} was not found!");
                 return false;
             }
         }
         $handlerOb = new $handlerClassPath();
         $classPathParts = explode("\\", $handlerClassPath);
         $handlersMap[$classPathParts[count($classPathParts) - 1]] = $handlerOb;
     }
     /* Create queue */
     $this->channel->queue_declare($queueName, false, true, false, false);
     /* Start consuming */
     $this->channel->basic_qos(null, 1, null);
     $this->channel->basic_consume($queueName, '', false, false, false, false, function ($amqpMsg) use($handlersMap) {
         $msg = Message::fromAMQPMessage($amqpMsg);
         Broker::handleMessage($msg, $handlersMap);
     });
     $this->logger->addInfo("Starting consumption of queue {$queueName}");
     /* Iterate until ctrl+c is received... */
     while (count($this->channel->callbacks)) {
         $this->channel->wait();
     }
 }
 public function actionIndex()
 {
     Yii::info('Started email task', __METHOD__);
     $this->setupConnection();
     echo '[*] Waiting for messages. To exit press CTRL+C', "\n";
     $this->channel->basic_qos(null, 1, null);
     $this->channel->basic_consume($this->queue, '', false, false, false, false, [$this, 'processEmail']);
     while (count($this->channel->callbacks)) {
         $this->channel->wait();
     }
     echo 'Shutting down...', "\n";
     Yii::info('Shutting down...', __METHOD__);
     Yii::trace('Disconnecting...', __METHOD__);
     $this->channel->close();
     $this->connection->close();
     return self::EXIT_CODE_NORMAL;
 }
 /**
  * Set the Quality Of Service settings for the given channel.
  *
  * Specify the amount of data to prefetch in terms of window size (octets)
  * or number of messages from a queue during a AMQPQueue::consume() or
  * AMQPQueue::get() method call. The client will prefetch data up to size
  * octets or count messages from the server, whichever limit is hit first.
  * Setting either value to 0 will instruct the client to ignore that
  * particular setting. A call to AMQPChannel::qos() will overwrite any
  * values set by calling AMQPChannel::setPrefetchSize() and
  * AMQPChannel::setPrefetchCount(). If the call to either
  * AMQPQueue::consume() or AMQPQueue::get() is done with the AMQP_AUTOACK
  * flag set, the client will not do any prefetching of data, regardless of
  * the QOS settings.
  *
  * @param integer $size The window size, in octets, to prefetch.
  * @param integer $count The number of messages to prefetch.
  *
  * @throws AMQPConnectionException If the connection to the broker was lost.
  *
  * @return bool TRUE on success or FALSE on failure.
  */
 public function qos($size, $count)
 {
     try {
         $this->channel->basic_qos($size, $count, false);
     } catch (Exception $e) {
         return false;
     }
     return true;
 }
Example #10
0
 /**
  * @throws \yii\base\InvalidConfigException
  */
 protected function initQueue()
 {
     /** @var Queue */
     $this->queue = Instance::ensure($this->queue, Queue::class);
     $this->channel = $this->queue->getChannel();
     $this->channel->basic_qos($this->prefetchSize, $this->prefetchCount, null);
     /**
      * Message consume callback wrapper
      *
      * @param AMQPMessage $message
      *
      * @throws Exception
      */
     $callback = function (AMQPMessage $message) {
         $this->messageCallback($message);
     };
     $this->consumerTag = $this->channel->basic_consume($this->queue->name, '', false, false, $this->noAck, false, $callback);
 }
Example #11
0
 /**
  * Initializes the message queue class
  *
  * @param \PhpAmqpLib\Channel\AMQPChannel $channel AMQP channel
  * @param string $queue Message queue name
  * @throws \Aimeos\MW\MQueue\Exception
  */
 public function __construct(\PhpAmqpLib\Channel\AMQPChannel $channel, $queue)
 {
     try {
         $channel->queue_declare($queue, false, true, false, false);
         $channel->basic_qos(null, 1, null);
     } catch (\Exception $e) {
         throw new \Aimeos\MW\MQueue\Exception($e->getMessage());
     }
     $this->channel = $channel;
     $this->queue = $queue;
 }
Example #12
0
 private function init()
 {
     $this->connection = new AMQPStreamConnection($this->host, $this->port, $this->user, $this->pass, '/', false, 'AMQPLAIN', null, 'en_US', 0);
     $this->channel = $this->connection->channel();
     $this->channel->queue_declare(self::QUEUE_NAME, false, true, false, false, false);
     $this->channel->exchange_declare(self::EXCHEAGE_NAME, 'direct');
     $this->channel->queue_bind(self::QUEUE_NAME, self::EXCHEAGE_NAME);
     $this->channel->queue_declare(self::QUEUE_WITH_DELAY_NAME, false, true, false, false, false, array('x-message-ttl' => array('I', self::DELAY * 1000), 'x-dead-letter-exchange' => array('S', self::EXCHEAGE_NAME)));
     $this->channel->exchange_declare(self::EXCHANGE_WITH_DELAY_NAME, 'direct');
     $this->channel->queue_bind(self::QUEUE_WITH_DELAY_NAME, self::EXCHANGE_WITH_DELAY_NAME);
     $this->channel->basic_qos(null, 1, null);
     register_shutdown_function([$this, 'shutdown'], $this->channel, $this->connection);
 }
Example #13
0
 /**
  * Setup consumer.
  */
 protected function setUpConsumer()
 {
     if (isset($this->exchangeOptions['name'])) {
         $this->channel->exchange_declare($this->exchangeOptions['name'], $this->exchangeOptions['type'], $this->exchangeOptions['passive'], $this->exchangeOptions['durable'], $this->exchangeOptions['auto_delete'], $this->exchangeOptions['internal'], $this->exchangeOptions['nowait'], $this->exchangeOptions['arguments'], $this->exchangeOptions['ticket']);
         if (!empty($this->consumerOptions['qos'])) {
             $this->channel->basic_qos($this->consumerOptions['qos']['prefetch_size'], $this->consumerOptions['qos']['prefetch_count'], $this->consumerOptions['qos']['global']);
         }
     }
     list($queueName, , ) = $this->channel->queue_declare($this->queueOptions['name'], $this->queueOptions['passive'], $this->queueOptions['durable'], $this->queueOptions['exclusive'], $this->queueOptions['auto_delete'], $this->queueOptions['nowait'], $this->queueOptions['arguments'], $this->queueOptions['ticket']);
     if (isset($this->exchangeOptions['name'])) {
         $this->channel->queue_bind($queueName, $this->exchangeOptions['name'], $this->routingKey);
     }
     $this->channel->basic_consume($queueName, $this->getConsumerTag(), false, false, false, false, array($this, 'processMessage'));
 }
Example #14
0
 /**
  *  Подключение к серверу
  *
  * @param bool $reconnect пепеподключение, если нужно
  * @return bool
  */
 protected function _connect($reconnect = true)
 {
     // уже подключены
     if (!$reconnect && $this->_connected) {
         return $this->_connected;
     }
     // отключаемся
     $this->_disconnect();
     try {
         // соединение
         $this->_Connection = new AMQPStreamConnection($this->_config['server']['host'], $this->_config['server']['port'], $this->_config['server']['user'], $this->_config['server']['password'], $this->_config['server']['vhost']);
         // канал
         $this->_Channel = $this->_Connection->channel();
         // можно отправить в очередь отдельно для каждого обработчика
         if (!empty($this->_config['qos'])) {
             $this->_Channel->basic_qos(null, $this->_config['qos'], null);
         }
         $this->_declare();
         $this->_connected = true;
     } catch (\Exception $e) {
         throw new Exception('Could not connect: ' . $e->getMessage(), $e->getCode());
     }
     return $this->_connected;
 }
 /**
  * @param ConsumerContainer $consumerContainer
  *
  * @throws ConsumerException
  */
 private function registerConsumerContainer(ConsumerContainer $consumerContainer)
 {
     $consumerName = $consumerContainer->getConsumerName();
     if (isset($this->consumerContainers[$consumerName])) {
         $currentConsumer = $this->consumerContainers[$consumerName];
         throw new ConsumerException(sprintf('Can not register consumer method [%s] because the consumer method [%s] already uses that name', $consumerContainer->getMethodName(), $currentConsumer->getMethodName()));
     }
     $this->channel->queue_declare($consumerName, false, true, false, false);
     foreach ($consumerContainer->getBindings() as $binding) {
         $this->channel->queue_bind($consumerName, $this->exchangeName, $binding);
     }
     $this->channel->basic_qos($consumerName, $consumerContainer->getPrefetchCount(), false);
     $this->channel->basic_consume($consumerName, '', false, false, false, false, function (AMQPMessage $message) use($consumerContainer) {
         $this->consume($consumerContainer, $message);
         $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
     });
     $this->consumerContainers[$consumerName] = $consumerContainer;
 }
 /**
  * @test
  */
 public function register_consumer_should_bind_queues()
 {
     $consumer = new stdClass();
     $binding2 = 'binding2';
     $binding1 = 'binding1';
     $consumerName = 'myName';
     $bindings = [$binding1, $binding2];
     $containerMock = $this->prophesize(ConsumerContainer::class);
     $containerMock->getBindings()->willReturn($bindings);
     $containerMock->getConsumerName()->willReturn($consumerName);
     $containerMock->getPrefetchCount()->willReturn(1);
     $this->parser->getConsumerMethods($consumer)->willReturn([$containerMock]);
     $this->channel->basic_qos($consumerName, 1, false)->shouldBeCalled();
     $this->channel->basic_consume($consumerName, Argument::any(), Argument::any(), Argument::any(), Argument::any(), Argument::any(), Argument::any())->shouldBeCalled();
     $this->channel->queue_declare($consumerName, Argument::any(), Argument::any(), Argument::any(), Argument::any())->shouldBeCalled();
     $this->channel->queue_bind($consumerName, self::EXCHANGE_NAME, $binding1)->shouldBeCalled();
     $this->channel->queue_bind($consumerName, self::EXCHANGE_NAME, $binding2)->shouldBeCalled();
     $this->manager->registerConsumer($consumer);
 }
Example #17
0
 /**
  * @inheritdoc
  */
 public function qos(int $size, int $count)
 {
     $this->channel->basic_qos($size, $count, false);
     $this->prefechSize = $size;
     $this->prefetchCount = $count;
 }
Example #18
0
 /**
  * Allows to specify basic quality of service for the channel or connection.
  *
  * The queue sends messages in advance to the consumer, so that when the client finishes processing a
  * message, the following message is already local, rather than needing to be sent down the channel.
  *
  * Pre-fetching gives a performance improvement, so this method allows to select the prefetch window in
  * bytes or select a maximum number of messages.
  *
  * If prefetchSize is set, the server will send a message in advance if it is equal to or smaller in size
  * than the available prefetch size. By default, there's no limit.
  *
  * If isGlobal is set to true, the QoS settings will be for all the channels using the connection, instead
  * of only to the channel setting the QoS rules.
  *
  * By default, the message broker pushes all the queue's messages to the clients as fast as the network and
  * the clients allow. The consumers will balloon in memory as they buffer all the messages in their own RAM.
  * The queue may appear empty if you ask the broker, but there may be millions of messages unacknowledged as
  * they sit in the consumers, ready for processing by the client application. Prefetch messages will not be
  * sent to new consumers connecting to the queue.
  *
  * @see  http://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/
  * @note This is only relevant with messages needing ack. If no-ack is set, QoS will be ignored.
  *
  * @param int  $prefetchSize  in bytes
  * @param int  $prefetchCount as number of messages
  * @param bool $isGlobal
  *
  * @return $this
  */
 public function setQualityOfService($prefetchSize, $prefetchCount, $isGlobal)
 {
     $this->channel->basic_qos($prefetchSize, $prefetchCount, $isGlobal);
     return $this;
 }
Example #19
0
 public function worker($callback)
 {
     $this->channel->basic_qos(null, 1, null);
     $this->channel->basic_consume('build_queue', '', false, false, false, false, $callback);
 }
 /**
  * @param int $size
  * @param int $count
  * @param boolean $global
  *
  * @return mixed
  */
 public function basic_qos($size, $count, $global = null)
 {
     return $this->channel->basic_qos($size, $count, $global);
 }
 /**
  * @param int $prefechCount
  */
 public function defineQoS($prefechCount = 1)
 {
     $this->channel->basic_qos(null, $prefechCount, null);
     $this->logger->info(sprintf('QoS defined (prefetch count: %s)!', $prefechCount));
 }