《RabbitMQ Tutorial》译文 第 3 章 发布和订阅 (3)

The producer program, which emits log messages, doesn't look much different from the previous tutorial. The most important change is that we now want to publish messages to our logs exchange instead of the nameless one. We need to supply a routingKey when sending, but its value is ignored for fanout exchanges. Here goes the code for EmitLog.cs file:

发出日志消息的生产者程序,与之前教程看起来并无太大不同。现在,最重要的变化莫过于我们想把消息发布到名为 logs 的交换器中,而非匿名。在发送消息时我们需要提供一个路由键(routingKey),只不过它的值在 fanout 型交换机中被忽略了,针对 EmitLog.cs 文件的代码如下:

using System; using RabbitMQ.Client; using System.Text; class EmitLog { 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: "logs", type: "fanout"); var message = GetMessage(args); var body = 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 string GetMessage(string[] args) { return ((args.Length > 0) ? string.Join(" ", args) : "info: Hello World!"); } }

(EmitLog.cs source)

As you see, after establishing the connection we declared the exchange. This step is necessary as publishing to a non-existing exchange is forbidden.

如同你所见,在建立好连接之后我们声明了交换机。这一步非常有必要,因为禁止向一个不存在的交换机发布消息。

The messages will be lost if no queue is bound to the exchange yet, but that's okay for us; if no consumer is listening yet we can safely discard the message.

如果尚没有任何队列绑定到交换机,消息将会丢失,但这对我们来说并没有什么问题;如果没有任何消费者正在监听,我们可以将消息安全地删除。

The code for ReceiveLogs.cs:

using System; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; class ReceiveLogs { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "logs", type: "fanout"); var queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: "logs", routingKey: ""); Console.WriteLine(" [*] Waiting for logs."); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] {0}", message); }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }

(ReceiveLogs.cs source)

Follow the setup instructions from tutorial one to generate the EmitLogs and ReceiveLogs projects.

从教程的第一章开始,跟随安装说明来生成 EmitLogs 和 ReceiveLogs 工程。

If you want to save logs to a file, just open a console and type:

如果你想保存日志到一个文件,只需打开控制台并输入:

cd ReceiveLogs dotnet run > logs_from_rabbit.log

If you wish to see the logs on your screen, spawn a new terminal and run:

如果你想在屏幕上查看日志,重开一个新的终端并运行:

cd ReceiveLogs dotnet run

And of course, to emit logs type:

当然,产生日志只需输入:

cd EmitLog dotnet run

Using rabbitmqctl list_bindings you can verify that the code actually creates bindings and queues as we want. With two ReceiveLogs.cs programs running you should see something like:

使用 rabbitmqctl list_bindings 命令你可以核实代码的确已经创建了我们期望的绑定和队列,伴随着 ReceiveLogs.cs 程序的运行你应该可以看到类似如下内容:

sudo rabbitmqctl list_bindings # => Listing bindings ... # => logs exchange amq.gen-JzTY20BRgKO-HjmUJj0wLg queue [] # => logs exchange amq.gen-vso0PVvyiRIL2WoV3i48Yg queue [] # => ...done.

The interpretation of the result is straightforward: data from exchange logs goes to two queues with server-assigned names. And that's exactly what we intended.

对结果的解释就非常简洁明了:来自 logs 交换机的数据将去往两个由服务端分配名称的队列,而这恰好是我们所期望的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzjfs.html