/** * Publishes the message and merges additional properties with basic properties * * @param string $msgBody * @param string $routingKey * @param array $additionalProperties * @param array $headers */ public function publish($msgBody, $routingKey = '', $additionalProperties = array(), array $headers = null) { if ($this->autoSetupFabric) { $this->setupFabric(); } $msg = new AMQPMessage((string) $msgBody, array_merge($this->getBasicProperties(), $additionalProperties)); if (!empty($headers)) { $headersTable = new AMQPTable($headers); $msg->set('application_headers', $headersTable); } $this->getChannel()->basic_publish($msg, $this->exchangeOptions['name'], (string) $routingKey); $this->logger->debug('AMQP message published', array('amqp' => array('body' => $msgBody, 'routingkeys' => $routingKey, 'properties' => $additionalProperties, 'headers' => $headers))); }
public function test_toMessageInterface_withProperRpcRequestTypeAMQMessage_returnsRpcRequestMessage() { $adaptor = new PhpAmqpLibMessageAdaptor(); $amqpMessage = new AMQPMessage(); $amqpMessage->set(MessageInterface::PROPERTY_TYPE, MessageInterface::TYPE_RPC_REQUEST); $amqpMessage->set(MessageInterface::PROPERTY_CONTENT_TYPE, MessageInterface::CONTENT_TYPE_PLAIN_TEXT); $message = $adaptor->toMessageInterface($amqpMessage); $this->assertTrue($message instanceof RpcRequestMessage, 'Returned value is not an instance of RpcRequestMessage'); }
/** * @param AMQPMessage $message * @param string $exchange * @param string $routingKey * * @return Invoker\Reply * * @throws \Exception */ public function call(AMQPMessage $message, $exchange = '', $routingKey = '') { $this->enqueue($reply = new Invoker\Reply($this)); try { $message->set('reply_to', $this->getReplyQueue()); $message->set('correlation_id', $reply->id()); $this->channel->basic_publish($message, $exchange, $routingKey); } catch (\Exception $e) { $this->dequeue($reply); throw $e; } return $reply; }
public static function createAmqpLibMessage(AmqpMessage $message, $persistent = true) { $amqpLibMessage = new AmqpLibMessage($message->getBody()); foreach (self::$PROPERTY_MAP as $name => $amqpLibName) { $value = $message->{'get' . ucfirst($name)}(); if ($value !== null) { $amqpLibMessage->set($amqpLibName, $value); } } $deliveryMode = $persistent ? self::DELIVERY_MODE_PERSISTENT : self::DELIVERY_MODE_NON_PERSISTENT; $amqpLibMessage->set('delivery_mode', $deliveryMode); return $amqpLibMessage; }
/** * Schedule a job in the future * * @access public * @param Job $job * @param DateTime $dateTime * @return $this */ public function schedule(Job $job, DateTime $dateTime) { $now = new DateTime(); $when = clone $dateTime; $delay = $when->getTimestamp() - $now->getTimestamp(); $message = new AMQPMessage($job->serialize(), array('delivery_mode' => 2)); $message->set('application_headers', new AMQPTable(array('x-delay' => $delay))); $this->channel->basic_publish($message, $this->exchange); return $this; }
public function testFrameOrder() { $msg = new AMQPMessage(''); $hdrs = new AMQPTable(array('x-foo' => 'bar')); $msg->set('application_headers', $hdrs); for ($i = 0; $i < $this->msg_count; $i++) { $this->ch->basic_publish($msg, $this->exchange_name, $this->queue_name); } $this->ch2->basic_consume($this->queue_name, '', false, true, false, false, array($this, 'process_msg')); while (count($this->ch2->callbacks)) { $this->ch2->wait(); } }
/** * Save the current message instance into de queue server * * @return void */ public function save() { try { $connection = new Connection($this->buildConnectionOptions()); $connection->open(); $msg = new AMQPMessage($this->message, array('content_type' => 'text/plain', 'delivery_mode' => 2)); if ($this->delay) { $headers = new AMQPTable(["x-delay" => $this->delay]); $msg->set('application_headers', $headers); } $connection->channel->basic_publish($msg, $this->queue_name); $connection->close(); } catch (Exception $e) { $connection->close(); throw new Exception($e); } }
/** * Sends message to queue * * @param string $queue The name of the queue * @param string $message The message to be publish * @param Object $params Contains headers for rmq message - * @return boolean */ public function send($queue, $message, $params) { if ($message === "") { $error_code = 1002; $error_detail = "The message to be posted to queue cannot be left blank:\n"; $this->logger->log_error($error_code, "Message is blank", $error_detail, __METHOD__); return FALSE; } if ($this->channel === NULL) { $this->connect(); } if ($this->connection->isConnected() === TRUE) { try { property_exists($params, "contentType") ? $contentType = $params->contentType : ($contentType = "application/JSON"); property_exists($params, "ttl") ? $Expiration = $params->ttl : ($Expiration = 604800000); property_exists($params, "Persistent") ? $Persistent = $params->Persistent : ($Persistent = 2); property_exists($params, "Priority") ? $Priority = $params->Priority : ($Priority = 1); property_exists($params, "delay") ? $valXdelay = $params->delay : ($valXdelay = 0); property_exists($params, "exchange") ? $exchangeName = $params->exchange and $queue = "" : ($exchangeName = ""); $messageId = uniqid(); $hdrs = new AMQPTable(array("x-delay" => $valXdelay)); $message = new AMQPMessage($message, array('content_type' => $contentType, 'delivery_mode' => $Persistent, 'expiration' => $Expiration, 'priority' => $Priority, 'message_id' => $messageId)); $message->set('application_headers', $hdrs); $this->channel->basic_publish($message, $exchangeName, $queue); return TRUE; } catch (AMQPTimeoutException $e) { $this->reconnect($message, $exchangeName, $queue); } catch (AMQPRuntimeException $e) { $this->reconnect($message, $exchangeName, $queue); } catch (Exception $e) { $error_code = 1499; $error_detail = "The message could not be sent to the Queue:\n" . $e->getMessage(); $this->logger->log_error($error_code, "Unable to send", $error_detail, __METHOD__); return FALSE; } // catch block ends here } else { $error_detail = "Not connected to RabbitMQ:\n"; $this->logger->log_error("", "RabbitMQ channel is no longer connected", $error_detail, __METHOD__); } }
/** * @inheritdoc */ public function publish(string $message, string $routingKey = '', int $flags = Constants::AMQP_NOPARAM, array $attributes = []) { $attributes['user_id'] = $this->getConnection()->getOptions()->getLogin(); $message = new AMQPMessage($message, $attributes); if (isset($attributes['headers'])) { $message->set('application_headers', new AMQPTable($attributes['headers'])); } $this->channel->getResource()->basic_publish($message, $this->name, $routingKey, (bool) ($flags & Constants::AMQP_MANDATORY), (bool) ($flags & Constants::AMQP_IMMEDIATE), null); }
<?php include __DIR__ . '/config.php'; use PhpAmqpLib\Connection\AMQPConnection; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Wire; $connection = new AMQPConnection(HOST, PORT, USER, PASS, VHOST); $channel = $connection->channel(); $exchName = 'topic_headers_test'; $channel->exchange_declare($exchName, 'topic', $passv = false, $durable = false, $autodel = true); $routing_key = empty($argv[1]) ? '' : $argv[1]; $data = implode(' ', array_slice($argv, 2)); if (empty($data)) { $data = "Hello World!"; } $msg = new AMQPMessage($data); $hdrs = new Wire\AMQPTable(array('x-foo' => 'bar', 'table' => array('figuf', 'ghf' => 5, 5 => 675), 'num1' => -4294967295, 'num2' => 5, 'num3' => -2147483648, 'true' => true, 'false' => false, 'void' => null, 'date' => new DateTime(), 'array' => array(null, 'foo', 'bar', 5, 5674625, 'ttt', array(5, 8, 2)), 'arr_with_tbl' => array('bar', 5, array('foo', 57, 'ee', array('foo' => 'bar', 'baz' => 'boo', 'arr' => array(1, 2, 3, true, new DateTime()))), 67, array('foo' => 'bar', 5 => 7, 8 => 'boo', 'baz' => 3)), '64bitint' => 9223372036854775807, '64bit_uint' => '18446744073709600000', '64bitint_neg' => -pow(2, 40))); $hdrs->set('shortshort', -5, Wire\AMQPTable::T_INT_SHORTSHORT); $hdrs->set('short', -1024, Wire\AMQPTable::T_INT_SHORT); echo PHP_EOL . PHP_EOL . 'SENDING MESSAGE WITH HEADERS' . PHP_EOL . PHP_EOL; var_dump($hdrs->getNativeData()); echo PHP_EOL; $msg->set('application_headers', $hdrs); $channel->basic_publish($msg, $exchName, $routing_key); echo " [x] Sent ", $routing_key, ':', $data, " \n"; $channel->close(); $connection->close();
/** * @param string $method * @param array $params * @return mixed */ public function call($method, $params) { $this->initAmqp(); $body = json_encode((object) array('method' => $method, 'params' => $params)); $this->setRequestId(uniqid()); $message = $this->getMessage(); if (!$message) { $message = new AMQPMessage($body, array('content_type' => 'text/plain', 'reply_to' => $this->getQueueDescriptor()->getName(), 'correlation_id' => $this->getRequestId())); } else { $message->body = $body; $message->set('correlation_id', $this->getRequestId()); $this->setMessage($message); } $endpoint = $this->getEndpoint(); $this->getChannel()->basic_publish($message, $endpoint->getExchange(), $endpoint->getRoute()); $this->getChannel()->basic_consume($this->getQueueDescriptor()->getName(), $this->getQueueDescriptor()->getName(), false, true, false, false, array($this, 'processMessage')); $this->setResponse(null); $start = microtime(true); while ($this->getResponse() === null) { if (microtime(true) - $start > $this->getTimeout() / 1000) { throw new TimeoutException("RPC call timed out"); } try { $this->getChannel()->wait(null, null, 0.001); } catch (AMQPTimeoutException $e) { // no-opp } } return $this->getResponse(); }
/** * @param \PhpAmqpLib\Message\AMQPMessage $message * @param string $exchange * @param string $routingKey * * @throws RuntimeException * @throws Exception|PhpAmqpLib\Exception\AMQPTimeoutException * @return mixed */ protected function doSendAndReceive(\PhpAmqpLib\Message\AMQPMessage $message, $exchange, $routingKey) { if ($message->has('correlation_id')) { throw new RuntimeException('Illegal API usage. RPC style exchange can only be used if no correlationId property is set on beforehand.'); } if ($message->has('reply_to')) { throw new RuntimeException('Illegal API usage. RPC style exchange can only be used if no replyTo property is set on beforehand.'); } $replyQueue = $this->replyQueue; $replyTimeoutInMs = $this->replyTimeoutInMs; $mandatory = $this->mandatory; $immediate = $this->immediate; return $this->execute(function (\PhpAmqpLib\Channel\AMQPChannel $channel) use($message, $exchange, $routingKey, $replyQueue, $replyTimeoutInMs, $mandatory, $immediate) { $correlationId = Tx_Amqp_Util_Randomizer::generateUUID(); if ($replyQueue === NULL) { // create a temporary (non-durable) exclusive auto-delete reply-queue list($replyQueue, , ) = $channel->queue_declare('', FALSE, FALSE, TRUE, TRUE); } $message->set('reply_to', $replyQueue); $message->set('correlation_id', $correlationId); $response = NULL; $callback = function (\PhpAmqpLib\Message\AMQPMessage $message) use($channel, $correlationId, &$response) { if ($correlationId == $message->get('correlation_id')) { $channel->basic_ack($message->delivery_info['delivery_tag']); $message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']); $response = $message->body; } }; $channel->basic_consume($replyQueue, '', FALSE, FALSE, FALSE, FALSE, $callback); $channel->basic_publish($message, $exchange, $routingKey, $mandatory, $immediate); while (count($channel->callbacks)) { try { $channel->wait(NULL, FALSE, (double) $replyTimeoutInMs / 1000.0); } catch (\PhpAmqpLib\Exception\AMQPTimeoutException $e) { // TODO: convert to own exception hierarchy? throw $e; } } return $response; }); }
/** * Push a raw payload onto the queue. * * @param string $payload * @param string $queue * @param array $options * * @return mixed */ public function pushRaw($payload, $queue = null, array $options = []) { $queue = $this->getQueueName($queue); $this->declareQueue($queue); if (isset($options['delay']) && $options['delay'] > 0) { list($queue, $exchange) = $this->declareDelayedQueue($queue, $options['delay']); } else { list($queue, $exchange) = $this->declareQueue($queue); } $headers = ['Content-Type' => 'application/json', 'delivery_mode' => 2]; if (isset($this->attempts) === true) { $headers['application_headers'] = [self::ATTEMPT_COUNT_HEADERS_KEY => ['I', $this->attempts]]; } // push job to a queue $message = new AMQPMessage($payload, $headers); $correlationId = $this->getCorrelationId(); $message->set('correlation_id', $correlationId); // push task to a queue $this->channel->basic_publish($message, $exchange, $queue); return $correlationId; }
/** * @param AMQPMessage $msg */ public function processMessage(AMQPMessage $msg) { $call = Call::fromJson($msg->body); try { $result = $this->call($call->getMethod(), $call->getArguments()); $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); // TODO cache message object & reuse $response = new AMQPMessage(json_encode($result), array('content_type' => 'text/plain')); $response->body = json_encode($result); $response->set('correlation_id', $msg->get('correlation_id')); $msg->delivery_info['channel']->basic_publish($response, '', $msg->get('reply_to')); // $msg->delivery_info['channel']->basic_ack( // $msg->delivery_info['delivery_tag']); } catch (\Exception $e) { // TODO return false echo "RPC Server Exception: " . $e->getMessage() . PHP_EOL; } }