RabbitMQ可以类比现实生活中的邮政服务。
现实中邮件服务处理的是邮件,发件人写好信件投入邮箱,邮递员收取信件存入邮局,邮局根据信件地址,分配邮递员投递信件到指定地点。
RabbitMQ与邮政服务的主要区别是RabbitMQ处理的是消息(二进制数据块), 即消息的接收、存储、分发。
发送消息的程序
等待接收消息的程序
RabbitMQ中的消息队列,就相当于邮政服务中的邮箱,所有通过RabbitMQ和你的应用程序发送接收的消息都存储在消息队列中,它是一个巨大的消息缓存,它的大小仅受服务器内存和硬盘空间的限制。
多个消息生产者可以通过同一个消息队列发送消息,多个消息消费者也可以通过同一个消息队列接收消息。
消息的生产者、消费者、消息队列不需要一定放置在同一个服务器中,现实中的大部分应用场景也不会允许他们放置在同一服务器中
这里我们创建2个控制台程序,一个负责发送简单的 Hello World消息,一个负责输出接收到的消息,并在控制台打印。
流程图如下,P为生产者,C为消费者,中间的红色块是消息队列
使用.NET Core的命令行工具,创建2个控制台程序,一个命名为Send, 另外一个命名为Receive。
dotnet new console –name Send dotnet new console –name Receive
使用.NET Core的命令行工具,分别为2个控制台程序添加RabbitMQ客户端程序集
dotnet add package RabbitMQ.Client dotnet restore
首先引入一些命名空间
using System; using RabbitMQ.Client; using System.Text;
然后在修改Main方法添加如下代码
var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { } }
connection对象抽象出了一个Socket连接,并负责RabbitMQ所使用的协议版本的验证和协商。
这里连接的是本地的RabbitMQ实例,所以使用的localhost作为主机名,如果需要连接其他服务器的RabbitMQ实例,只需要将主机名变更为对应服务器的ip地址即可。
然后我们需要创建一个channel对象,大部分的消息处理有关的api都是在channel对象中。
接下来,为了发送消息,我们需要创建一个消息队列,然后向这个消息队列中发布消息。
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()) using(var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", 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(); } }
Channel对象的QueueDeclare方法是用来声明一个消息队列的,这个方法是等幂的,即只要当该消息队列不存在的时候才创建他,如果已经存在,就直接返回之前创建的对象。
RabbitMQ中传递的消息是二进制数据,所以需要将传递的文本转换成二进制数据。
这样消息发送程序就完成了。
前面我们做的发送程序运行一次只发送一条消息,与发送程序不同,接收消息程序需要监听接收到的所有消息,并打印。
首先我们引入需要使用的命名空间
using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text;
初始的设置代码和发送程序一样
public static void Main() { 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); } } }
这里还要重复声明一次消息队列的原因是,你不能保证在消息接收程序启动时,消息队列一定存在(即消息接收程序的启动早于发送消息程序)。
由于消息的推送是异步的,所以这里我们需要使用事件来捕捉消息,并打印在控制台
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); 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(); }
在消息发送程序和消息接收程序目录下,使用.NET Core命令行工具启动2个项目
dotnet run转载于:https://www.cnblogs.com/lwqlun/p/9095118.html
相关资源:数据结构—成绩单生成器