Beispiel #1
0
 public function publish($message, $routingKey = null, array $headers = [])
 {
     if (!$this->getMeta()) {
         throw new BunnyException("Could not create meta class {$this->metaClassName}.");
     }
     if (is_string($message)) {
         $message = $this->meta->fromJson($message);
     }
     if ($this->beforeMethod) {
         $this->{$this->beforeMethod}($message, $this->manager->getChannel());
     }
     switch ($this->contentType) {
         case ContentTypes::APPLICATION_JSON:
             if ($this->meta instanceof JsonMetaInterface) {
                 $message = $this->meta->toJson($message);
             } else {
                 throw new BunnyException("Cannot serialize message to JSON.");
             }
             break;
         case ContentTypes::APPLICATION_PROTOBUF:
             if ($this->meta instanceof ProtobufMetaInterface) {
                 $message = $this->meta->toProtobuf($message);
             } else {
                 throw new BunnyException("Cannot serialize message to Protobuf.");
             }
             break;
         default:
             throw new BunnyException("Unhandled content type '{$this->contentType}'.");
     }
     if ($routingKey === null) {
         $routingKey = $this->routingKey;
     }
     $headers["content-type"] = $this->contentType;
     $this->manager->getChannel()->publish($message, $headers, $this->exchange, $routingKey, $this->mandatory, $this->immediate);
 }
Beispiel #2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $consumerName = strtolower($input->getArgument("consumer-name"));
     if (!isset($this->consumers[$consumerName])) {
         throw new \InvalidArgumentException("Consumer '{$consumerName}' doesn't exists.");
     }
     $consumerArgv = $input->getArgument("consumer-parameters");
     array_unshift($consumerArgv, $consumerName);
     $this->manager->setUp();
     $channel = $this->manager->getChannel();
     $consumer = $this->container->get($this->consumers[$consumerName][0]->name);
     $maxMessages = PHP_INT_MAX;
     $maxSeconds = PHP_INT_MAX;
     $calledSetUps = [];
     $tickMethod = null;
     $tickSeconds = null;
     foreach ($this->consumers[$consumerName] as $consumerSpec) {
         $maxMessages = min($maxMessages, $consumerSpec->maxMessages ?: PHP_INT_MAX);
         $maxSeconds = min($maxSeconds, $consumerSpec->maxSeconds ?: PHP_INT_MAX);
         if (empty($consumerSpec->queue)) {
             $queueOk = $channel->queueDeclare("", false, false, true);
             if (!$queueOk instanceof MethodQueueDeclareOkFrame) {
                 throw new BunnyException("Could not declare anonymous queue.");
             }
             $consumerSpec->queue = $queueOk->queue;
             $bindOk = $channel->queueBind($consumerSpec->queue, $consumerSpec->exchange, $consumerSpec->routingKey);
             if (!$bindOk instanceof MethodQueueBindOkFrame) {
                 throw new BunnyException("Could not bind anonymous queue.");
             }
         }
         if ($consumerSpec->prefetchSize || $consumerSpec->prefetchCount) {
             $qosOk = $channel->qos($consumerSpec->prefetchSize, $consumerSpec->prefetchCount);
             if (!$qosOk instanceof MethodBasicQosOkFrame) {
                 throw new BunnyException("Could not set prefetch-size/prefetch-count.");
             }
         }
         $meta = null;
         if ($consumerSpec->meta) {
             /** @var MetaInterface $metaClassName */
             $metaClassName = $consumerSpec->meta;
             if (!class_exists($metaClassName)) {
                 throw new BunnyException("Consumer meta class {$metaClassName} does not exist.");
             }
             if (!method_exists($metaClassName, "getInstance")) {
                 throw new BunnyException("Method {$metaClassName}::getInstance() does not exist.");
             }
             $meta = $metaClassName::getInstance();
         }
         if ($consumerSpec->setUpMethod && !isset($calledSetUps[$consumerSpec->setUpMethod])) {
             if (!method_exists($consumer, $consumerSpec->setUpMethod)) {
                 throw new BunnyException("Init method " . get_class($consumer) . "::{$consumerSpec->setUpMethod} does not exist.");
             }
             $consumer->{$consumerSpec->setUpMethod}($channel, $channel->getClient(), $consumerArgv);
             $calledSetUps[$consumerSpec->setUpMethod] = true;
         }
         if ($consumerSpec->tickMethod) {
             if ($tickMethod) {
                 if ($consumerSpec->tickMethod !== $tickMethod) {
                     throw new BunnyException("Only single tick method is supported - " . get_class($consumer) . ".");
                 }
                 if ($consumerSpec->tickSeconds !== $tickSeconds) {
                     throw new BunnyException("Only single tick seconds is supported - " . get_class($consumer) . ".");
                 }
             } else {
                 if (!$consumerSpec->tickSeconds) {
                     throw new BunnyException("If you specify 'tickMethod', you have to specify 'tickSeconds' - " . get_class($consumer) . ".");
                 }
                 if (!method_exists($consumer, $consumerSpec->tickMethod)) {
                     throw new BunnyException("Tick method " . get_class($consumer) . "::{$consumerSpec->tickMethod} does not exist.");
                 }
                 $tickMethod = $consumerSpec->tickMethod;
                 $tickSeconds = $consumerSpec->tickSeconds;
             }
         }
         $channel->consume(function (Message $message, Channel $channel, Client $client) use($consumer, $consumerSpec, $meta) {
             $this->handleMessage($consumer, $consumerSpec, $meta, $message, $channel, $client);
         }, $consumerSpec->queue, $consumerSpec->consumerTag, $consumerSpec->noLocal, $consumerSpec->noAck, $consumerSpec->exclusive, false, $consumerSpec->arguments);
     }
     $startTime = microtime(true);
     while (microtime(true) < $startTime + $maxSeconds && $this->messages < $maxMessages) {
         $channel->getClient()->run($tickSeconds ?: $maxSeconds);
         if ($tickMethod) {
             $consumer->{$tickMethod}($channel, $channel->getClient());
         }
     }
     $channel->getClient()->disconnect();
 }