RabbitMQ translation 04--Publish and subscribe

Source: Internet
Author: User

Publish/Subscribe

In the previous case, we created a task force, which is the idea of an average assignment of each task to each performer, and in this article we'll do something different and send a message to multiple consumers, a pattern called "Publish/Subscribe."

To illustrate this pattern, we are going to create a simple log system, one responsible for publishing messages, and the other responsible for receiving printing them.

In our log system, every running copy of the recipient will get a message, which allows us to run a receiver to save the message to disk while another consumer can print the message to the screen.

Essentially, publishing a log message will be broadcast to all recipients

Switch (exchanges)

In the previous article, we accepted and sent the message through a queue, and now it's time to introduce all the work models of RABBITMQ.

Let's take a quick look at the model we've been involved in

--producer (publisher), is a user application that is responsible for sending messages.

--queue, responsible for storing messages

Consumer (recipient), the user program responsible for receiving the message.

The core idea of RABBITMQ is that producers will never send messages directly to the queue, and in fact the producers often don't even know whether a given message can have a queue to receive it.

Accordingly, the producer can only send messages to the switch, the switch works very simply, on the one hand it receives the message from the producer, on the other hand it sends the message to the corresponding queue. The switch must know how to handle the received message, should it be placed in a special queue? Should it be placed in more than one queue? or whether it needs to be ignored.

The way this work is handled is achieved through the switch type.

There are several switch types available: direct,topic,headers,fanout We'll focus on the last one (fanout), let's create a fanout switch named ' logs '

Channel. Exchangedeclare ("logs""fanout");

This fanout switch function is very simple (you may have guessed his way from the name), broadcast the received message to all known queues, this is what our log system needs.

List the switches that RABBITMQ has added:

Cmd:rabbitmqctl list_exchanges

No named switches: In the previous case we knew nothing about the switch, but we could still send the message to the queue because we were using a default interactive machine with a null name (""), and a look back at the way we sent the message

var message = GetMessage (args); var body ="" ""Hello"null, Body:body);

The first parameter is the name of the switch, and an empty string represents the default unnamed switch: The message is sent to the queue through the presence of the Routingkey.

Now we send the named switch instead:

var message = GetMessage (args); var body ="logs"""null,  body:body);
Temporary queue

In the previous case, the queue we used was a named queue (remember hello and Task_queue ), naming a team name is strict, we need the same queue that the performer connects to work on, It is important to specify a queue name when you want to share a queue between producers and consumers. But our log system is not,

We want to listen to all the log messages, not just their subsets, we are only interested in the current flow of messages, not the old news, the end of this problem we need 2 things.

First of all, whenever we connect to the queue, we need a fresh, empty queue, in order to achieve this goal we can create a random name queue each time, or more convenient way-let the service for our queue randomly named.

Second, once we are disconnected from the consumer-to-queue connection, we need to automatically delete the queue.

In the. NET client, we use the Queuedeclare () method without a parameter to create a randomly named non-persistent, automatically deleted exclusive queue.

var queuename = Channel. Queuedeclare (). QueueName;

QueueName is a random queue name, such as:AMQ.GEN-JZTY20BRGKO-HJMUJJ0WLG.

Binding

We have created a fanout switch and a queue, and now we need to tell us that the switch sends the message to our queue, the relationship between the switch and the queue is called binding.

" logs " "");

From now on logs the switch will put the message into our queue.

List Queues Cmd:rabbitmqctl list_bindings

Summary

The producer responsible for sending the message is basically the same as the previous case, the biggest difference being that we send the message to our named queue logs instead of the default queue, we need to use Routingkey when we send it, but its value is ignored by the fanout switch.

EmitLog.cs

classemitlog{ Public Static voidMain (string[] args) {        varFactory =NewConnectionFactory () {HostName ="localhost" }; using(varConnection =Factory. CreateConnection ())using(varChannel =connection. Createmodel ()) {channel. Exchangedeclare (Exchange:"logs", type:"fanout"); varMessage =GetMessage (args); varBODY =Encoding.UTF8.GetBytes (message); Channel. Basicpublish (Exchange:"logs", Routingkey:"", Basicproperties:NULL, Body:body); Console.WriteLine ("[x] Sent {0}", message); } Console.WriteLine ("Press [Enter] to exit.");    Console.ReadLine (); }    Private Static stringGetMessage (string[] args) {        return(args. Length >0)               ?string. Join (" ", args):"Info:hello world!"); }}

As you can see, we created a queue after the connection was established, which is necessary because it is not allowed to send to a non-existent switch.

Messages that are sent when the queue is not bound to the switch are lost, but this is not a problem for our log system, and we can safely ignore this message when there is no consumer listening.

ReceiveLogs.cs:

classreceivelogs{ Public Static voidMain () {varFactory =NewConnectionFactory () {HostName ="localhost" }; using(varConnection =Factory. CreateConnection ())using(varChannel =connection. Createmodel ()) {channel. Exchangedeclare (Exchange:"logs", type:"fanout"); varQueueName =Channel. Queuedeclare ().            QueueName; Channel. Queuebind (queue:queuename,exchange:"logs", Routingkey:""); Console.WriteLine ("[*] waiting for logs."); varConsumer =NewEventingbasicconsumer (channel); Consumer. Received+ = (model, ea) = =            {                varBODY =ea.                Body; varMessage =Encoding.UTF8.GetString (body); Console.WriteLine ("[x] {0}", message);            }; Channel. Basicconsume (Queue:queuename, Noack:true, Consumer:consumer); Console.WriteLine ("Press [Enter] to exit.");        Console.ReadLine (); }    }}

Running two receive simultaneously, you can see that two receivers can receive one message at a time.

RabbitMQ translation 04--Publish and subscribe

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.