Implement RabbitMQ Messaging Between Two Laravel
Implementing RabbitMQ messaging between two Laravel applications involves several steps. RabbitMQ is a message broker that enables communication between different services or components in a distributed system. In this scenario, you’ll have a producer Laravel application that sends messages to a RabbitMQ exchange, and a consumer Laravel application that listens for and processes those messages.Here’s a step-by-step guide:
Install RabbitMQ:
Verify the installation and running status of RabbitMQ by consulting the earlier article I provided on how to install RabbitMQ.
Install Laravel Project
Install Laravel on both the producer and consumer applications using Composer:
composer create-project --prefer-dist laravel/laravel producer-app
composer create-project --prefer-dist laravel/laravel consumer-app
A “producer” and a “consumer” refer to components or applications that play specific roles in the communication process. Let’s briefly define each:
- Producer-App:
Role: The producer is responsible for creating and sending messages to a message broker or queue.
Functionality:
- Message Creation: It generates messages containing information or tasks that need to be processed.
- Message Sending: It sends the messages to a message broker (such as RabbitMQ) for distribution to consumers.
Example Use Case: In a web application, the producer might be responsible for generating notifications, logging events, or dispatching tasks for background processing.
2.Consumer-App:
Role: The consumer is responsible for receiving and processing messages from a message broker or queue.
Functionality:
- Message Retrieval: It retrieves messages from a message broker or queue.
- Message Processing: It performs the necessary actions or tasks based on the content of the received messages.
- Acknowledgment: It may acknowledge the successful processing of a message, confirming its receipt.
Example Use Case: In a background processing system, the consumer might listen for messages related to tasks, process them, and update the system’s state accordingly.
Example Scenario:
Producer-App:
- Language/Framework: Laravel (PHP)
- Functionality: Generates messages for a notification system.
- Implementation: Uses RabbitMQ to send messages containing notification details to a queue.
Consumer-App:
- Language/Framework: Laravel (PHP)
- Functionality: Processes incoming messages and sends notifications.
- Implementation: Uses RabbitMQ to listen for messages in the queue, retrieves them, and triggers the appropriate notification actions.
Communication Flow:
- The producer-app generates a message and sends it to a message queue using a message broker (e.g., RabbitMQ).
- The consumer-app is constantly listening to the message queue.
- When a new message arrives in the queue, the consumer-app retrieves it.
- The consumer-app processes the message, performing the required actions (e.g., sending a notification).
- The consumer-app acknowledges the successful processing of the message.
- The producer-app and consumer-app can continue this communication process asynchronously.
Install RabbitMQ PHP Library:
In both Laravel applications, install the php-amqplib
library to interact with RabbitMQ:
composer require php-amqplib/php-amqplib
Producer and Consumer Application Configuration:
Configure in both Laravel application to send messages to RabbitMQ. Update the .env
file with RabbitMQ connection details:
RABBITMQ_HOST=your_rabbitmq_host
RABBITMQ_PORT=5672
RABBITMQ_USER=your_rabbitmq_user
RABBITMQ_PASSWORD=your_rabbitmq_password
RABBITMQ_VHOST=your_rabbitmq_vhost
Create a new RabbitMQ service class or use an existing one to handle message sending for Producer Laravel Application:
<?php
namespace App\Services;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class RabbitMQService
{
private $connection;
private $channel;
public function __construct()
{
$this->connection = new AMQPStreamConnection(
env('RABBITMQ_HOST'),
env('RABBITMQ_PORT'),
env('RABBITMQ_LOGIN'),
env('RABBITMQ_PASSWORD'),
env('RABBITMQ_VHOST')
);
$this->channel = $this->connection->channel();
}
public function sendMessage(string $queue, string $message)
{
$this->channel->queue_declare($queue, false, true, false, false);
$msg = new AMQPMessage($message);
$this->channel->basic_publish($msg, '', $queue);
}
public function __destruct()
{
$this->channel->close();
$this->connection->close();
}
}
In your producer laravel application, use the RabbitMQ service to send messages:
<?php
namespace App\Http\Controllers;
use App\Services\RabbitMQService;
class MessageController extends Controller
{
public function sendMessage()
{
$rabbitmqService = new RabbitMQService();
$rabbitmqService->sendMessage('2dbCM', 'Hello RabbitMQ!');
return response()->json(['message' => 'Message sent successfully']);
}
}
Now let’s makes our required routes in routes/web.php
Route::get('/test',[MessageController::class,'sendMessage']);
Create a new RabbitMQ service class or use an existing one to handle message sending for Consumer Laravel Application:
<?php
namespace App\Services;
use PhpAmqpLib\Connection\AMQPStreamConnection;
class RabbitMQService
{
private $connection;
private $channel;
public function __construct()
{
$this->connection = new AMQPStreamConnection(
env('RABBITMQ_HOST'),
env('RABBITMQ_PORT'),
env('RABBITMQ_LOGIN'),
env('RABBITMQ_PASSWORD'),
env('RABBITMQ_VHOST')
);
$this->channel = $this->connection->channel();
}
public function consumeMessages(string $queue, callable $callback)
{
$this->channel->queue_declare($queue, false, true, false, false);
$this->channel->basic_consume($queue, '', false, true, false, false, $callback);
while (count($this->channel->callbacks)) {
$this->channel->wait();
}
}
public function __destruct()
{
$this->channel->close();
$this->connection->close();
}
}
Create an artisan command to consume messages in consume laravel application:
<?php
namespace App\Console\Commands;
use App\Services\RabbitMQService;
use Illuminate\Console\Command;
class ConsumeMessages extends Command
{
protected $signature = 'consume:messages';
protected $description = 'Consume messages from RabbitMQ';
public function handle()
{
$rabbitmqService = new RabbitMQService();
$rabbitmqService->consumeMessages('2dbCM', function ($message) {
// Process the message here
$this->info("Received message: {$message->getBody()}");
});
}
}
Run the consumer command to start listening for messages in consume laravel application:
php artisan consume:messages
Now, when you send a message from the producer application, the consumer application should receive and process it.Keep in mind that this is a basic setup, and you might need to enhance it based on your specific use case, such as error handling, message acknowledgment, etc