Official website: http://www.rabbitmq.com/tutorials/tutorial-four-python.html
In the previous example, we built a simple log system. We can broadcast a log message to all recipients.
In this example, we are going to add a new feature. We will be able to subscribe only to part of the message. For example, we can simply write a critical error type message to the log file (save to disk space), but also print all the log messages to the console.
Bindings (binding)
In the previous example, we have created bindings. As follows:
Amqp_channel:call (channel, # ' Queue.bind ' {exchange = << "Logs" >>, Qu Eue = Queue}),
The binding links Exchange and queue together. This can be easily understood as: This queue is interested in this exchage.
The Bindings can take extra routing_key parameters. In order to remove confusion about the Basic_publish parameter, we will call it binding key. Here's how we create a binding from a key.
[Amqp_channel:call (channel, # ' Queue.bind ' {exchange = << "Direct_logs" >> Routing_key = List_to_binary (Severity), queue = queue}) | | Severity <-ARGV],
The meaning of the binding key depends on the type of exchange. The fanout type of exchange we used earlier ignores the value of the binding key.
Direct Exchange
The previous log System example broadcasts all messages to all consumers. We want to extend it so that it allows filtering information.
With fanout type of exchange, there won't be much flexibility, just broadcasting.
With direct-type exchange, direct Exchange's algorithm is simple, and messages with the routing key and the same binding key for the queue are delivered to the queue. See:
This setting, we can see that there are two queues bound to a direct type of exchange. Q1 's binding key is orange,
Q2 's binding key is black and green.
In this system, if the routing key of the message band is orange, the message is delivered to Q1, and if the message's routing key is black or green, the messages are posted to Q2, and the other messages are discarded.
Multiple bindings
The same binding can bind multiple queues. In the Q1 and Q2, the binding key is black, in which case the direct type of exchange will be the same as the fanout type, and the broadcast message to all matching queues.routing key black messages will be sent to Q1 and Q2.
Emitting logs
Our log system will use the model above, and we will send a message to the direct type of exchange instead of the Fanout type. We will provide the severity of the log as routing key. The application that receives the message will be able to select the message for the severity it wants to receive. Let's focus first on sending logs.
First, we need to create a echange:
Amqp_channel:call (channel, # ' Exchange.declare ' {exchange = << "Direct_logs" >> Type = << "direct" >>}),
In addition, we are ready to send a message:
Amqp_channel:cast (channel, # ' Basic.publish ' {exchange = << "Direct_logs" & Gt;>, Routing_key = Severity}, #amqp_msg {payload = Message}),
One simple thing: we will evaluate the severity as: ' Info ', ' warning ', one of ' error '.
Subscribing (Order)
The program that receives the message is almost the same as the previous example: We will create a new binding for each severity that we are interested in.
[Amqp_channel:call (channel, # ' Queue.bind ' {exchange = << "Direct_logs" >> Routing_key = List_to_binary (Severity), queue = queue}) | | Severity <-ARGV],
Putting it all together
Emit_log_direct.erl
-module (Emit_log_direct).-compile ([Export_all]).-include_lib ("Amqp_client/include/amqp_client.hrl"). Main (ARGV) -> {ok, Connection} = amqp_connection:start (#amqp_params_network {host = "localhost"}), {ok, channel} = amqp_connection:open_channel (Connection), amqp_channel:call ( channel, # ' Exchange.declare ' {exchange = << "Direct_logs" >>, type = << "direct" >>}), {Severity, Message} = case Argv of [] -> {<< "Info" >>, << "hello world!" >>}; [S] -> {list_to_binary (S), << "hello world!" >>}; [s | msg] -> {list_to_binary (S), list_to_ Binary (String:join (msg, " "))} end, amqp_channel:cast (channel, # ' Basic.publish ' { exchange = << "Direct_logs" >>, routing_key = Severity}, #amqp_msg {payload = message}), io:format (" [x] sent ~p:~p~n ", [severity, message]), ok = amqp_channel:close ( Channel), ok = amqp_connection:close (connection), ok.
Receive_logs_direct.erl
-module (Receive_logs_direct).-compile ([Export_all]).-include_lib ("Amqp_client/include/amqp_client.hrl"). Main ( ARGV) -> {ok, Connection} = amqp_connection:start (#amqp_params_network {host = "localhost"}), {ok, channel} = amqp_connection:open_channel (Connection), amqp_channel:call ( channel, # ' Exchange.declare ' {exchange = << "Direct_logs" >>, type = << "direct" >>}), # ' QUEUE.DECLARE_OK ' {queue = queue} = amqp_Channel:call (channel, # ' Queue.declare ' {exclusive = true}), [amqp_channel : Call (channel, # ' Queue.bind ' {exchange = << "Direct_logs" >>, routing_key = list_to_binary (Severity), queue = queue}) | | severity <- argv], io:format (" [*] Waiting for Logs. to exit press&nbsP Ctrl+c~n "), amqp_channel:subscribe (channel, # ' Basic.consume ' {queue = queue, no _ack = true}, self ()), receive # ' Basic.consume_ok ' {} -> ok end, loop (Channel ). Loop (Channel) -> receive {# ' Basic.deliver ' {routing_key = routingkey}, #amqp_msg {payload = body}} -> io:format (" [x] ~p:~p~n", [ Routingkey, boDY]), loop (Channel) end.
RabbitMQ Erlang "Routing"