RabbitMQ original translated 05 -- routing, rabbitmq translated 05 -- Routing
In the previous article, we built a simple log system that can broadcast messages to multiple recipients.
In this article, I will add some functions to make it possible to accept some messages. For example, we only record error messages on disk, at the same time, all messages can be printed to the screen.
Bind
In the previous case, we have created a binding and can call the following code again:
channel.QueueBind(queue: queueName,exchange: "logs",routingKey: "");
Binding is the relationship between the vswitch and the queue. It can be simply understood that the queue is interested in messages on the vswitch.
The routingKey parameter can be set for binding. To avoid confusion with parameters of the BasicPublish method, we call it binding key for the moment. Below is a binding with the specified binding key:
channel.QueueBind(queue: queueName,exchange: "direct_logs",routingKey: "black");
Direct exchange
Our previous log System Broadcasts the received messages to all the recipients. We will expand it so that it can filter and send messages based on the message level, for example, we want the log receiver to accept only error messages of severity level, instead of wasting disk space on warning and information level messages.
Fanout cannot provide us with such flexibility. It can only directly broadcast the received messages without worrying about the routing key.
Here we use a direct switch instead. The implementation idea of a direct switch is very simple-the message will be sent to the queue with its Binding key and the routing key exactly match.
To illustrate this problem, consider the following settings:
Two queues are bound to the vswitch. The bingding key bound to the first queue is "orange", and the second queue is bound with two binding keys, one being "black ", the other is "green". In this configuration, if a message with a routing key of "orange" is routed to the queue Q1, messages with a routing key of "black" or "green" will be routed to the queue Q2.
Multiple bindings
It is completely legal to bind multiple queues with a routing key. In our case, we can add a binding with the binding key "black" in both route X and queue Q1 and Q2, in this case, route X will send the matched message to all recipients like the fanout switch: the route will send the message with the routing key "black" to Q1 and Q2.
Embedded log
We use this mode to build our log system. Instead of fanout, we will send our messages to the direct type switch. We use the log level as the rouing key of the route, in this way, the receiver can choose to accept logs of interest based on the log level.
As usual, first we need to create a switch:
channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
Then we prepare to send the message:
var body = Encoding.UTF8.GetBytes(message);channel.BasicPublish(exchange: "direct_logs",routingKey: severity,basicProperties: null, body: body);
We simply assume that severity is divided into the following types: "info", "warning", "error ".
Subscription
The only difference between accepting messages is that we will create a new binding for each level of messages we are interested in:
var queueName = channel.QueueDeclare().QueueName;foreach(var severity in args){ channel.QueueBind(queue: queueName,exchange: "direct_logs",routingKey: severity);}
Summary
EmitLogDirect. cs:
Class EmitLogDirect {public static void Main (string [] args) {var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. createConnection () using (var channel = connection. createModel () {channel. exchangeDeclare (exchange: "direct_logs", type: "direct"); var severity = (args. length> 0 )? Args [0]: "info"; var message = (args. Length> 1 )? String. Join ("", args. Skip (1). ToArray (): "Hello World! "; Var body = Encoding. UTF8.GetBytes (message); channel. basicPublish (exchange: "direct_logs", routingKey: severity, basicProperties: null, body: body); Console. writeLine ("[x] Sent '{0}': '{1}'", severity, message);} Console. writeLine ("Press [enter] to exit. "); Console. readLine ();}}View Code
Cancelogsdirect. cs:
Class cancelogsdirect {public static void Main (string [] args) {var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. createConnection () using (var channel = connection. createModel () {channel. exchangeDeclare (exchange: "direct_logs", type: "direct"); var queueName = channel. queueDeclare (). queueName; if (args. length <1) {Console. error. writeLine ("Usage: {0} [info] [warning] [error]", Environment. getCommandLineArgs () [0]); Console. writeLine ("Press [enter] to exit. "); Console. readLine (); Environment. exitCode = 1; return;} foreach (var severity in args) {channel. queueBind (queue: queueName, exchange: "direct_logs", routingKey: severity);} Console. writeLine ("[*] Waiting for messages. "); var consumer = new EventingBasicConsumer (channel); consumer. stored ed + = (model, ea) =>{ var body = ea. body; var message = Encoding. UTF8.GetString (body); var routingKey = ea. routingKey; Console. writeLine ("[x] received' {0} ':' {1} '", routingKey, message) ;}; channel. basicConsume (queue: queueName, noAck: true, consumer: consumer); Console. writeLine ("Press [enter] to exit. "); Console. readLine ();}}}View Code
Compile and execute the Code:
For example, if you only want to save "warning" and "error" messages, open the console and enter "cancelogsdirect.exe warning error ".
Send an Error message. Enter EmitLogDirect.exe error "Run. Run. Or it will explode." on the console ."