This extension provide integration of Bunny/Bunny.
The simplest way to install Portiny/RabbitMQ is using Composer:
$ composer require portiny/rabbitmq
Usage is pretty simple. Just create your own consumers/exchanges/producers/queues classes which inherits from abstract classes from this package. Then implement required methods and register them into Nette DI container.
<?php declare(strict_types=1);
namespace App\Service\Exchange;
use Portiny\RabbitMQ\Exchange\AbstractExchange;
final class LogExchange extends AbstractExchange
{
protected function getName(): string
{
return 'logExchange';
}
protected function getType(): string
{
return self::TYPE_FANOUT;
}
}
<?php declare(strict_types=1);
namespace App\Service\Queue;
use Portiny\RabbitMQ\Queue\AbstractQueue;
use Portiny\RabbitMQ\Queue\QueueBind;
final class LogQueue extends AbstractQueue
{
protected function getName(): string
{
return 'log';
}
protected function getBindings(): array
{
return [
new QueueBind('logExchange')
];
}
}
<?php declare(strict_types=1);
namespace App\Service\Producer;
use Exception;
use Portiny\RabbitMQ\Producer\AbstractProducer;
use Portiny\RabbitMQ\Producer\Producer;
final class LogProducer extends AbstractProducer
{
/**
* @var Producer
*/
private $producer;
public function __construct(Producer $producer)
{
$this->producer = $producer;
}
public function logException(Exception $exception)
{
$body = [
'code' => $exception->getCode(),
'message' => $exception->getMessage()
];
$this->producer->produce($this, json_encode($body));
}
protected function getHeaders(): array
{
return [
'content-type' => self::CONTENT_TYPE_APPLICATION_JSON,
'delivery-mode' => self::DELIVERY_MODE_PERSISTENT,
];
}
protected function getExchangeName(): string
{
return 'logExchange';
}
protected function getRoutingKey(): string
{
return ''; // we have fanout exchange so routing key can be empty
}
}
<?php declare(strict_types=1);
namespace App\Service\Consumer;
use Bunny\Message;
use Portiny\RabbitMQ\Consumer\AbstractConsumer;
final class LogConsumer extends AbstractConsumer
{
protected function getQueueName(): string
{
return 'log';
}
protected function process(Message $message): int
{
$exception = json_decode($message->content);
echo $exception->message;
// do something with $exception
return self::MESSAGE_ACK;
}
}
Then register example classes into DI container (syntax depends on your framework).
# Nette Framework (for integration use https://github.com/portiny/graphql-nette)
services:
- App\Service\Exchange\LogExchange
- App\Service\Queue\LogQueue
- App\Service\Producer\LogProducer
- App\Service\Consumer\LogConsumer
# Symfony Framework (for integration use https://github.com/portiny/graphql-symfony)
services:
App\Service\Exchange\LogExchange: ~
App\Service\Queue\LogQueue: ~
App\Service\Producer\LogProducer: ~
App\Service\Consumer\LogConsumer: ~
You have two ways how to declare exchange and queue into RabbitMQ. If you use Symfony/Console then simply run command rabbitmq:declare
.
bin/console rabbitmq:declare
If you don't use Symfony/Console simply inject Portiny\RabbitMQ\BunnyManager
into your class and call declare()
method.
<?php declare(strict_types=1);
namespace App\Service;
use Portiny\RabbitMQ\BunnyManager;
class MyDeclarator
{
/**
* @var BunnyManager
*/
private $bunnyManager;
public function __construct(BunnyManager $bunnyManager)
{
$this->bunnyManager = $bunnyManager;
}
public function declare(): void
{
$this->bunnyManager->declare();
}
}
It's simple! Just call logException
method on App\Service\Producer\LogProducer
e.g.:
<?php declare(strict_types=1);
namespace App\Control;
use App\Service\Producer\LogProducer;
use Exception;
use Nette\Application\UI\Control;
final class ClickControl extends Control
{
/**
* @var LogProducer
*/
private $logProducer;
public function __construct(LogProducer $logProducer)
{
$this->logProducer = $logProducer;
}
public function handleClick(int $x, int $y)
{
try {
// some logic
} catch (Exception $exception) {
$this->logProducer->logException($exception);
}
}
}
At first add alias to TestConsumer
(syntax depends on your framework).
# Nette Framework (for integration use https://github.com/portiny/graphql-nette)
rabbitmq:
aliases:
logger: App\Service\Consumer\LogConsumer
# Symfony Framework (for integration use https://github.com/portiny/graphql-symfony)
parameters:
portiny.rabbitmq.aliases:
logger: App\Service\Consumer\LogConsumer
Use Symfony/Console and simply run command rabbitmq:consume
.
Consumer App\Service\Consumer\LogConsumer
will consume 20 messages and then die.
bin/console rabbitmq:consume logger --messages 20
Consumer App\Service\Consumer\LogConsumer
will consumimg for 30 seconds and then die.
bin/console rabbitmq:consume logger --time 30