Skip to content
Advertisement

How to use Symfony Messenger component in standalone code to send AMQP messages

We’re using Symfony Messenger in a Symfony 5 project to integrate with RabbitMQ. It works fine when sending messages within Symfony, but I need the ability to use the Messenger component to send messages from some legacy PHP applications that are not built with the Symfony framework.

Under Symfony, it handles all the magic by injecting the MessageBusInterface and all I need to do is something like this:

    public function processTestMessage(MessageBusInterface $bus)
    {
        $bus->dispatch(new TestMessage('Hello World!');
    }

I need to somehow instantiate my own version of $bus that will send AMQP messages the same way that Symfony does. I’ve been trying to recreate everything that Symfony does behind the scenes to accomplish this, but have not been able to put all the details together.

The crux of the problem is to create my own SendMessageMiddleware that does the same thing as Symfony. After that, it’s simple:

    $sendersLocator = ???
    $eventDispatcher = ???

    $sendMessageMiddleware = new($sendersLocator, $eventDispatcher);
    $bus = new MessageBus([$sendMessageMiddleware]);

Does anyone have any examples of working code that uses the Messenger component to send AMQP messages outside of Symfony?

Advertisement

Answer

This can be improved but it works for me:

use SymfonyComponentMessengerBridgeAmqpTransportAmqpSender;
use SymfonyComponentMessengerBridgeAmqpTransportConnection;
use SymfonyComponentMessengerEnvelope;
use SymfonyComponentMessengerMessageBus;
use SymfonyComponentMessengerMiddlewareSendMessageMiddleware;
use SymfonyComponentMessengerTransportSenderSendersLocatorInterface;

$sendersLocator = new class implements SendersLocatorInterface {
    public function getSenders(Envelope $envelope): iterable
    {
        $connection = new Connection(
            [
                'hosts' => 'localhost',
                'port' => 5672,
                'vhosts' => '/',
                'login' => 'guest',
                'password' => 'guest'
            ],
            [
                'name' => 'messages'
            ],
            [
                'messages' => []
            ]
        );
        return [
            'async' => new AmqpSender($connection)
        ];
    }
};

$middleware = new SendMessageMiddleware($sendersLocator);

$bus = new MessageBus([$middleware]);

$bus->dispatch(new MyMessage());
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement