Enhancing PHP Code Productivity with RabbitMQ | Lucideus Research

There are often situations wherein some independent but important programming actions need to be done. However, since most of the scripting languages like PHP and Python are synchronous, waiting for those tasks to finish, in order for the code to proceed, is not economical from the point of view of time taken and performance. The main code and the independent action can be made to work simultaneously without any inter-dependency. This asynchronous handling is made possible with help of RabbitMQ.

What is RabbitMQ?
RabbitMQ is an open source message broker software (message-oriented middleware). It is an intermediary program module that translates a formally defined message from the formal messaging protocol of the sender, performs some action on it and then sends it to the formal messaging protocol of the receiver.

It uses the Advanced Message Queuing Protocol (AMQP) to forward messages. AMQP is an open standard application layer protocol for message-oriented middleware. The defining features of AMQP are message orientation, queuing, routing (including point-to-point and publish-and-subscribe), reliability and security

The following diagram describes basic functioning of RabbitMQ 

The data structure used by RabbitMQ for storing messages is Queue. A Producer is a program that generates messages to be stored in the queue and a Consumer is a program that reads messages from queue and performs some action on the messages. RabbitMQ supports multiple producers and consumers over a single channel. 

Installing RabbitMQ on Ubuntu
Following are the commands to install RabbitMQ -

  • sudo apt-get install rabbitmq-server
  • sudo service rabbitmq-server start

Implementation - Integrating PHP with RabbitMQ
This library is a pure PHP implementation of the AMQP 0-9-1 protocol. PHP uses php-amqplib module to implement queueing through RabbitMQ.
Following are the commands to install php-amqplib -

  • sudo apt-get install php7.0-mbstring
  • sudo apt-get install php7.0-bcmath
  • composer require php-amqplib/php-amqplib

These commands fetch the required libraries and its dependencies inside the vendor folder of the CodeIgniter project.

Following is a simple example of the usage of RabbitMQ through CodeIgniter in PHP 

In producer’s code, we need to include the library and use the necessary classes: 
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

Then we can create a connection to the server:
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

The connection abstracts the socket connection, and takes care of protocol version negotiation, authentication etc. Here we connect to a broker on the local machine - hence the localhost. 

Next we create a channel, which is where most of the API for getting things done resides.
$channel = $connection->channel();

To send, we must declare a queue for us to send to; then we can publish a message to the queue:
$channel->queue_declare('hello', false, false, false, false);
$msg = new AMQPMessage('Hello World!');
$channel->basic_publish($msg, '', 'hello');

Lastly, we close the channel and the connection;

In consumer’s code:

Setting up is the same as the publisher; we open a connection and a channel, and declare the queue from which we're going to consume. This matches up with the queue that producer publishes to.

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);

We now define a PHP callable that will receive the messages sent by the server. Messages are sent asynchronously from the server to the clients.

$callback = function($msg) 
  echo " [x] Received ", $msg->body, "\n";
$channel->basic_consume('hello', '', false, true, false, false, $callback);
while(count($channel->callbacks)) {
Our code will block while our $channel has callbacks. Whenever we receive a message our $callback function will be passed the received message.


Post a Comment