What happens if we break our contract and send a message with one or four words, like "orange" or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.
如果我们打破约定将会发生什么呢?比如发送一个字符串或者四个字符串,类似于“orange”或者“quick.orange.male.rabbit”。
On the other hand "lazy.orange.male.rabbit", even though it has four words, will match the last binding and will be delivered to the second queue.
另一方面像“lazy.orange.male.rabbit”,即使它有四个字符串,但仍然会匹配最后一个绑定(lazy.#)并被递送到第二个队列。
Topic exchange 话题交换机Topic exchange is powerful and can behave like other exchanges.
话题(Topic)交换机很强大,它可以表现得类似其他交换机。
When a queue is bound with "#" (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.
当一个队列采用"#"作为绑定键时,它将接收到所有的消息而忽略掉路由键,这就像是 fanout 型交换机一样。
When special characters "*" (star) and "#" (hash) aren't used in bindings, the topic exchange will behave just like a direct one.
当特殊字符"*" (星号) and "#" (哈希,井号)都没有应用到绑定中时,topic 型交换机将表现得与 direct 型一样。
Putting it all together 融合一起We're going to use a topic exchange in our logging system. We'll start off with a working assumption that the routing keys of logs will have two words: ".".
我们即将在日志系统中使用 topic 型交换机,首先从一个假定的工作前替起步,即拟定日志的路由键为两个字符串:"."
The code is almost the same as in the previous tutorial.
其代码与之前教程几乎相同。
The code for EmitLogTopic.cs:
EmitLogTopic.cs 类文件代码:
using System; using System.Linq; using RabbitMQ.Client; using System.Text; class EmitLogTopic { 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: "topic_logs", type: "topic"); var routingKey = (args.Length > 0) ? args[0] : "anonymous.info"; var message = (args.Length > 1) ? string.Join(" ", args.Skip( 1 ).ToArray()) : "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "topic_logs", routingKey: routingKey, basicProperties: null, body: body); Console.WriteLine(" [x] Sent '{0}':'{1}'", routingKey, message); } } }The code for ReceiveLogsTopic.cs:
ReceiveLogsTopic.cs 类文件代码:
using System; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; class ReceiveLogsTopic { 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: "topic_logs", type: "topic"); var queueName = channel.QueueDeclare().QueueName; if(args.Length < 1) { Console.Error.WriteLine("Usage: {0} [binding_key...]", Environment.GetCommandLineArgs()[0]); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); Environment.ExitCode = 1; return; } foreach(var bindingKey in args) { channel.QueueBind(queue: queueName, exchange: "topic_logs", routingKey: bindingKey); } Console.WriteLine(" [*] Waiting for messages. To exit press CTRL+C"); var consumer = new EventingBasicConsumer(channel); consumer.Received += (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, autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }Run the following examples:
运行示例:
To receive all the logs:
接收所有的日志:
cd ReceiveLogsTopic dotnet run "#"To receive all logs from the facility "kern":
只接收来自“kern”设备的日志:
cd ReceiveLogsTopic dotnet run "kern.*"Or if you want to hear only about "critical" logs:
或者你只想关心“critical”级别的日志:
ReceiveLogsTopic.exe "*.critical"You can create multiple bindings:
你可以创建多重绑定:
cd ReceiveLogsTopic dotnet run "kern.*" "*.critical"And to emit a log with a routing key "kern.critical" type:
基于路由键“kern.critical”来产生日志,可以输入:
cd EmitLogTopic dotnet run "kern.critical" "A critical kernel error"Have fun playing with these programs. Note that the code doesn't make any assumption about the routing or binding keys, you may want to play with more than two routing key parameters.
程序执行起来还是很令人愉快的,要注意的是,这些代码并没有针对路由键或者绑定键做任何预设 ,你可能会需要用到超出两个以上的路由键参数。
(Full source code for EmitLogTopic.cs and ReceiveLogsTopic.cs)
( EmitLogTopic.cs 和 ReceiveLogsTopic.cs 完整代码)
posted @