In the previous article rabbitmq Message Queuing (v): Routing message routing, we implemented a simple log system. Consumer can listen for logs of different severity (severity levels). However, this is why it is called a simple log system, because it is only possible to set through the severity (severity level). More standards are not supported.
For example syslog Unix Log utility, it can pass severity (Info/warn/crit ...) and module (Auth/cron/kern ...). This is probably what we want: we can just need the log of the Cron module.
To achieve similar functionality, we need to use topic Exchange.
1. Topic Exchange
The routing_key of a message is limited and cannot be made arbitrary. The format is the dot "." The segmented character descriptor. For example: "Stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit". You can put any key in the Routing_key, of course, the longest can not exceed 255 bytes.
For Routing_key, there are two special characters (called metacharacters in regular Expressions):
- * (asterisk) to represent any one word
- # (pound) 0 or more words
Take a look at the following example:
Producer the message needs to be set Routing_key,routing_key contains three words and two dot numbers.
The first key is the description of celerity (Dexterity, agility), the second is colour (color), and the third one is species (species): "<celerity>.<colour>.<species>".
Here we create two bindings: Q1 's binding key is "*.orange.*"; Q2 's binding key is "*.*.rabbit" and "lazy.#":
- Q1 interested in all orange-colored animals
- Q2 interested in all the rabbits and all the lazy
For example Routing_key is "quick.orange.rabbit" will be sent to Q1 and Q2. The message "Lazy.orange.elephant" is also sent to Q1 and Q2. But "Quick.orange.fox" is sent to Q1; "Lazy.brown.fox" is sent to Q2. "Lazy.pink.rabbit" is also sent to Q2, but even though two routing_key are matched, it is only sent once. "Quick.brown.fox" will be discarded.
What if you send a word that's not 3? The answer depends on the situation, because # is able to match 0 or any of the words. such as "orange" or "quick.orange.male.rabbit", they will be discarded. If it is lazy then it will enter the Q2. There is a similar "lazy.orange.male.rabbit", although it contains four words.
Topic Exchange and other Exchange
Because of the "*" (star)and "#" (hash), Topic Exchange is very powerful and can be converted to other Exchange:
If Binding_key is "#"-It will receive all the message, no matter what Routing_key is, it is like Fanout exchange.
If "*" (Star) and "#" (hash) is not used, then topic Exchange becomes direct exchange.
2. Code implementation
Now we are going to refine the log system of our last article. Routing keys has two parts: "<facility>.<severity>".
Producer.cs
1 /// <summary>2 ///using topics for message distribution3 ///for Routing_key, there are two special characters (called metacharacters in regular expressions):4 ///* (asterisk) to represent any one word5 ///# (hash) of 0 or more words6 /// </summary>7 class Program8 {9 /// <summary>Ten /// One /// </summary> A /// <param name= "args" > - ///SendDemo6.exe "Wang.yun" "A Critical kernel error" - /// </param> the Static voidMain (string[] args) - { - varFactory =NewConnectionFactory () {HostName ="localhost" }; - using(varConnection =Factory. CreateConnection ()) + { - using(varChannel =connection. Createmodel ()) + { AChannel. Exchangedeclare ("Topic_logs", "topic" );//using the topic for message distribution, Exchange is automatically bound to the queue's name as routing key when it is created by the queue. at - varRoutingkey = (args. Length >0) ? args[0] :"Anonymous.info"; - varMessage = (args. Length >1) -?string. Join (" ", args. Skip (1). ToArray ()) -:"Hello world!"; - varBODY =Encoding.UTF8.GetBytes (message); inChannel. Basicpublish ("Topic_logs", Routingkey,NULL, body); -Console.WriteLine ("[x] Sent ' {0} ': ' {1} '", Routingkey, message); to } + } - } the}
Consumer. cs
1 /// <summary>2 /// 3 /// </summary>4 /// <param name= "args" >5 ///RecieveDemo6.exe "#"6 ///RecieveDemo6.exe "wang.*"7 ///RecieveDemo6.exe "*.yun"8 ///RecieveDemo6.exe "wang.*" "*.yun"9 /// </param>Ten Static voidMain (string[] args) One { A varFactory =NewConnectionFactory () {HostName ="localhost" }; - using(varConnection =Factory. CreateConnection ()) - { the using(varChannel =connection. Createmodel ()) - { -Channel. Exchangedeclare ("Topic_logs","Topic")///receiver if closed, automatically created queue is automatically deleted - varQueueName =Channel. Queuedeclare ();//Get the name of the queue + - if(args. Length <1) + { AConsole.Error.WriteLine ("Usage: {0} [Binding_key ...]", Environment.getcommandlineargs () [0]); atEnvironment.exitcode =1; - return; - } - - foreach(varBindingkeyinchargs) - { inChannel. Queuebind (QueueName,"Topic_logs", Bindingkey); - } to +Console.WriteLine ("[*] waiting for messages."+"To exit Press CTRL + C"); - the varConsumer =NewQueueingbasicconsumer (channel); *Channel. Basicconsume (QueueName,true, consumer); $ Panax Notoginseng while(true) - { the varEA =(Basicdelivereventargs) consumer. Queue.dequeue (); + varBODY =ea. Body; A varMessage =Encoding.UTF8.GetString (body); the varRoutingkey =ea. Routingkey; +Console.WriteLine ("[x] Received ' {0} ': ' {1} '", Routingkey, message); - } $ } $ } -}
This example is the same as the fifth article.
Turn:
Http://www.rabbitmq.com/tutorials/tutorial-five-dotnet.html (official)
http://blog.csdn.net/anzhsoft/article/details/19633079 (translation)
RABBITMQ Message Queuing (vi): Using topics for message distribution [go]