RabbitMq learning 4- Publish / Subscribe (Publish / Subscribe)

First, publish / subscribe

Distribute a message to multiple consumers (consumers). This mode is called "publish / subscribe."

To describe this model, we will build a simple logging system. It consists of two procedures - programs responsible for sending a message log, the second program is responsible for obtaining and outputting the message contents.

In this log system, all receivers running programs will accept the message. We use one receiver (Receiver) The log write hard drive, a further receiver (Receiver) log output to the screen.

Finally, the log message is broadcast to all recipients (receivers).

Second, the switch (Exchanges)

  • Publisher (producer) is the application dissemination of information.
  • Queue (Queue) a buffer for storing messages.
  • Consumers (consumer) is an application to receive the message.

The core idea is RabbitMQ messaging models: the publisher (producer) does not send any message directly to the queue. In fact, the publisher (producer) do not even know whether the message has been delivered to the queue.

Publisher (producer) just need to send a message to a switch (exchange). Exchanger is very simple, while it receives the message from the publisher side, while the push message queue. Switch must know how to process the message it received, should be pushed to a specified queue or multiple queues, or ignore the message. These rules are by exchange type defined.

There are several to choose switch type:

AMQPEXTYPEDIRECT

AMQPEXTYPEFANOUT

AMQPEXTYPEHEADER  or AMQPEXTYPETOPIC

Here the main explanation AMQPEXTYPE_FANOUT. Create a fanout type of switch, named logs:

$exchange->setName('logs'); $exchange->setType(AMQP_EX_TYPE_FANOUT); $exchange->declareExchange(); 

fanout switch is very simple, you might be able to guess from the name, it sends a message to all queues it knows. This is what we needed logging system.

Now, we can send a message to the named switch:

$exchange->publish($message, '');

Third, the temporary queue

To a queue name is very important - we need workers (workers) point to the correct queue. If you intend to share the same queue between the publisher (producers) and consumers (consumers), then to the queue name is very important.

But this does not apply to our logging system. We intend to receive all log messages, rather than just a small part. We are concerned that the latest news instead of the old. To solve this problem, we need to do two things.

First of all, when we connect RabbitMQ, we need a new, empty queue. We can create a random queue name manually, or let the server pick a random queue name (recommended) for us . We just call the $ queue-> declareQueue (); when the method does not provide a queue parameters on it:

$queue = new AMQPQueue($channel); $queue->setFlags(AMQP_EXCLUSIVE); $queue->declareQueue(); 

At this time we can pass $ queue-> getName (); get a random queue name has been generated. It might be like this: amq.gen-U0srCoW8TsaXjNh73pnVAw ==.

The second step, when the consumer (consumer) disconnected, the queue should be deleted. We can use exclusive logo.$queue->setFlags(AMQP_EXCLUSIVE);

Fourth, the binding

A fanout exchange type and a queue we've created. Now we need to tell the switch how to send a message to our queue. The relationship between the exchange and the queue we call the binding (binding).

$queue->bind($exchangeName, $queue->getName()); 

Now, logs switch will add to our message queue.

Fifth, the code integration

  1, the producer: send_log.php

  

<?php

/**
 * PHP amqp(RabbitMQ) Demo-3
 */

$exchangeName = 'logs';
$message = empty($argv[1]) ? 'info:Hello World!' : ' '.$argv[1];

$connection = new AMQPConnection(array('host' => '127.0.0.1', 'port' => '5672', 'vhost' => '/', 'login' => 'guest', 'password' => 'guest'));
$connection->connect() or die("Cannot connect to the broker!\n");

$channel = new AMQPChannel($connection);
Exchange $ = new new AMQPExchange ( $ Channel );
 $ Exchange -> the setName ( $ exchangeName );
 $ Exchange -> setType (AMQP_EX_TYPE_FANOUT); // send a message to all queues it knows about 
$ Exchange -> declareExchange (); 

$ Exchange -> publish ( $ Message , '' );
 var_dump ( "[X] Sent $ Message " ); 

$ Connection -> the disconnect ();
View Code

  2. Consumer: receive_logs.php

  

<?php

/**
 * PHP amqp(RabbitMQ) Demo-3
 */
$exchangeName = 'logs';

$connection = new AMQPConnection(array('host' => '127.0.0.1', 'port' => '5672', 'vhost' => '/', 'login' => 'guest', 'password' => 'guest'));
$connection->connect() or die("Cannot connect to the broker!\n");

$channel = new AMQPChannel($connection);

$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
 $ Exchange -> setType (AMQP_EX_TYPE_FANOUT); // send a message to all queues it knows about 
$ Exchange -> declareExchange (); 

$ Queue = new new AMQPQueue ( $ Channel );
 $ Queue -> setFlags (AMQP_EXCLUSIVE); // when the consumer (consumer) disconnected, the queue should be deleted 
$ queue -> declareQueue (); // create a random queue name 
$ queue -> the bind ( $ exchangeName , '' ); 

var_dump ( '. [*] Waiting messages for the To Exit Press the CTRL + C' );  
 the while ( TRUE ) {  
         $ Queue->consume('callback');
}
$connection->disconnect();

function callback($envelope, $queue) {  
        $msg = $envelope->getBody();
        var_dump(" [x] Received:" . $msg);
        $queue->nack($envelope->getDeliveryTag());
}
View Code

So we're done. If you want to save the log to a file, just open the console input:

$ php receive_logs.php > logs_from_rabbit.log

If you want to see the log in screen, then open a new terminal and run:

$ php receive_logs.php

Of course, send log:

$ php send_log.php
 

Guess you like

Origin www.cnblogs.com/ivy-zheng/p/10967884.html