"<p>I have been working on a project (a game) with my friends and we faced some performance issues when it comes to players logs.<br /> We needed to log every action of the player also we needed to call some services remotely at the same time.<br /> We’ve thought about using an asynchronous middleware that we can implement between our Node Js server and our backend.<br /> After some research we found RabbitMQ a middleware message oriented and asynchronous.</p> <h2><strong>What is RabbitMQ? </strong></h2> <p>RabbitMQ is a messaging broker - an intermediary for messaging. It gives your applications a common platform to send and receive messages, and your messages a safe place to live until received.<br /> Also, it’s lightweight and easy to deploy on premises and in the cloud. It supports multiple messaging protocols (AMQP, MQTT STOMP)</p> <p>In this short post, we will setup RabbitMQ in a Symfony 5 project using the messenger component of Symfony. We already published a tutorial that clarify all the steps above and more : <a href="https://devbrains.tn/tutorials/discover-rabbitmq-with-symfony-5-project">RabbitMQ Tutorial</a></p> <h2><strong>What is Symfony messenger Component?</strong></h2> <p>Messenger centers around two different classes that you'll create:</p> <p>1- A message class that holds data</p> <p>2- A handler(s) class that will be called when that message is dispatched. The handler class will read the message class and perform one or more tasks.</p> <h3><strong>Requirements: </strong></h3> <p>1- Symfony (we will use the version 5.4)</p> <p>2- Messenger Component</p> <p>3- RabbitMQ Instance</p> <p>4- AMQP Protocol defined and configured in php.ini (<a href="https://devbrains.tn/tutorials/how-to-fix-amqp-extension-is-not-installed">Tutorial</a>)</p> <p> </p> <h3><strong>Creating our Symfony 5.4 Project:</strong></h3> <pre> <code>symfony new rabbitmq-demo --version=5.4 –full</code></pre> <p><strong>Installing Messenger Component: </strong></p> <pre> <code>composer require messenger</code></pre> <p><strong>Create your RabbitMQ instance:</strong></p> <p>1- Create your RabbitMQ Instance on <a href="https://www.cloudamqp.com/">cloudamqp.com</a>.</p> <p>2- Next, via the RabbitMQ manager visit the queue tab and add a queue.</p> <p>To communicate With RabbitMQ we need to a protocol named AMQP.</p> <p><strong>What is AMQP?  </strong></p> <p>AMQP (for Advanced Message Queuing Protocol) is an open protocol for middleware-oriented messaging systems developed by the JPMorgan Chase1 bank. The objective of AMQP is to standardize exchanges between message servers based on the following principles: oriented message, use of queues, routing (point to point and publish-subscribe), reliability, and security.</p> <p>We already published a tutorial to simplify this task: <a href="https://devbrains.tn/tutorials/how-to-fix-amqp-extension-is-not-installed">How to Fix AMQP extension is not installed</a> </p> <p><strong>Define the Structure of the message</strong></p> <p>We need to define the structure of our message so we will create an entity via maker bundle:</p> <pre> <code>php bin/console make entity</code></pre> <p>Entity name : MyMessage</p> <p>Attribute 1 : Sender (String,255, nullable)</p> <p>Attribute 2 : Receiver (String,255, nullable)</p> <p>Attribute 3 :  content (String,255, nullable)</p> <p><strong>Communicate RabbitMQ with our Symfony Application:</strong></p> <p>We need to copy the information of our instance (user,password,host..) in the .env:</p> <pre> <code>MESSENGER_TRANSPORT_DSN=amqp://USER:PASSWORD@HOSTNAME.rmq.cloudamqp.com/USER/QUEUE_NAME</code> </pre> <p><strong>Configure our Messenger Component:</strong></p> <pre> <code>framework: messenger: transports: async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: # Route your messages to the transports 'App\Entity\MyMessage': async</code> </pre> <h3><strong>Send messages to RabbitMQ:</strong></h3> <p>Now we will create a controller via make bundle</p> <pre> <code><kbd>php bin/console make:controller</kbd></code></pre> <p>Controller Name : HomeController</p> <p>Next, we'll instantiate an object from our Entity MyMessage and using our dispatch method defined in our MessageBusInterface, we'll send the message to our RabbitMQ queue.</p> <pre> <code><?php namespace App\Controller; use App\Entity\MyMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; class HomeController extends AbstractController { /** * @Route("/home", name="home") */ public function index(MessageBusInterface $bus): Response { $message= new MyMessage(); $message->setSender("John"); $message->setReceiver("Jack"); $message->setContent("Hello"); $bus->dispatch($message); return new Response("Message sent"); } }</code> </pre> <p>Now let’s run our web server:</p> <pre> <code>Symfony server:start</code></pre> <p>If everything is done correctly, we should see in the tab overview in our RabbitMQ instance a message queued.</p> <p><strong>Consuming the messages:</strong></p> <p>To consume the messages, we need to add a handler that will handle our message when consuming.</p> <pre> <code><?php namespace App\MessageHandler; use App\Entity\MyMessage; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; class MyMessageHandler implements MessageHandlerInterface { public function __invoke(MyMessage $message) { echo "Welcome to MyMessage Handler \n"; echo $message->getContent()."\n" ; } }</code> </pre> <p>Finally it’s time to consume the queued messages via the command :</p> <pre> <code>php bin/console messenger:consume -v</code></pre> <p>That’s it 😊</p> <p>I hope everything works as expected, if you have any question don’t hesitate to ask on our <a href="https://devbrains.tn/forum">forum</a>.</p> <p>Some Useful Resources : </p> <p>Repository Link : <a href="https://github.com/HoussemTN/rabbitmq-demo">RabbitMQ-demo</a><br /> RabbitMQ Tutorials : <a href="https://www.rabbitmq.com/getstarted.html">RabbitMQ Docs</a></p> <p> </p>"