RabbitMQ学习之HelloWorld(1)
RabbitMQ就是一个消息代理(message broker),可以用来接收和发送消息。
消息队列有一些黑话,我们来看下:
- Producer : 发送message的程序
- Queue : 可以用来存储message
- Consumer : 接收message的程序
注意,producer 和 consumer 和 queue 可以在同一台主机,也可以不在同一台主机。通常不在
Hello World
如图,P表示producer , C 表示consumer . 中间的盒子表示queue
Sending
发送message的producer
Send.cs
using System;using RabbitMQ.Client;using System.Text; class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) //建立连接,如果我们想连接到一个不同机器的broker,我们可以指定一个名字或者ip using(var channel = connection.CreateModel()) //建立通道,大多数api获取数据都在这里 { channel.QueueDeclare(queue: "hello", //声明一个queue(用来把message发送过去) durable: false, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", //实际发送的动作 routingKey: "hello", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } }
如果你第一次使用RabbitMQ,并且发送message失败。那么有可能是the broker(代理:指RabbitMQ 或者说queue)启动的时候没有足够的硬盘空间(默认需要至少50M)因此拒绝接受请求。
你可以检查the broker 的日志文件来确认并且减少限制。详细 configuration file documentation
Receiving
对于consumer ,它用来从RabbitMQ监听message.所以,它会持续监听message.
Receive.cs
using RabbitMQ.Client;using RabbitMQ.Client.Events;using System;using System.Text; class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) //建立连接 using(var channel = connection.CreateModel()) //建立通道 { channel.QueueDeclare(queue: "hello", //声明queue durable: false, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => //回调函数 { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "hello", //接受消息动作 autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }
注意,我们在这里也声明了queue.因为我们可能在启动publisher之前先启动consumer,所以我们在consume messages之前需要确保queue存在。
我们在接收queue中的message时是异步的,所以我们提供了一个回调函数。即 EventingBasicConsumer.Received
实际效果及代码改进
代码结构如下
本示例直接在一个解决方案中建立了两个控制台程序,用来send和receive 队列queue中的message.
代码使用上面讲述的代码,
效果如下:
上面的代码直接在程序启动后就发送了message.使看起来不是很直观,下面是对send.cs修改后的代码。
send.cs
public static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); while (true) { var message = Console.ReadLine(); //string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); //Console.WriteLine(" Press [exit] to exit."); } } //Console.WriteLine(" Press [enter] to exit."); //Console.ReadLine(); }
如上代码,使用while循环稍作修改,是可以持续手动输入message
效果如下
如上,可以看出,当想要持续发送时,我们在发送端加了while循环。
但是,接收端却不需要做任何修改,因为接收端本身是在持续监听queue里的message。
参考网址:RabbitMQ