【转】.Net使用RabbitMQ即时发消息Demo
原文地址:https://www.jb51.net/article/143496.htm
参考地址:https://www.cnblogs.com/xibei666/p/5931267.html
1.使用VS的NuGet安装包管理工具安装RabbitMQ.Client:

2.生产者端代码:
namespace RMQProducter { class Program { /// <summary> /// 连接配置 /// </summary> private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest", Port = 5672 }; /// <summary> /// 路由名称 /// </summary> const string ExchangeName = "Jent.Exchange"; /// <summary> /// 队列名称 /// </summary> const string QueueName = "Jent.Queue"; static void Main(string[] args) { DirectExchangeSendMsg(); Console.WriteLine("输入任意值退出程序!"); Console.ReadKey(); } /// <summary> /// 单点精确路由模式 /// </summary> private static void DirectExchangeSendMsg() { using (IConnection conn = rabbitMqFactory.CreateConnection()) { using (IModel channel = conn.CreateModel()) { channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName); var props = channel.CreateBasicProperties(); props.Persistent = true; Console.WriteLine("请输入需要发送的消息:"); string vadata = Console.ReadLine(); while (vadata != "exit") { var msgBody = Encoding.UTF8.GetBytes(vadata); channel.BasicPublish(exchange: ExchangeName, routingKey: QueueName, basicProperties: props, body: msgBody); Console.WriteLine(string.Format("发送时间:{0},发送完毕,输入exit退出消息发送", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); vadata = Console.ReadLine(); } } } } } }
3,消费者代码
namespace RMQCustomer { class Program { /// <summary> /// 连接配置 /// </summary> private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest", Port = 5672 }; /// <summary> /// 路由名称 /// </summary> const string ExchangeName = "Jent.Exchange"; /// <summary> /// 队列名称 /// </summary> const string QueueName = "Jent.Queue"; static void Main(string[] args) { DirectAcceptExchange(); Console.WriteLine("输入任意值退出程序!"); Console.ReadKey(); } private static void DirectAcceptExchange() { using (IConnection conn = rabbitMqFactory.CreateConnection()) { using (IModel channel = conn.CreateModel()) { channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName); while (true) { BasicGetResult msgResponse = channel.BasicGet(QueueName, noAck: false); if (msgResponse != null) { var msgBody = Encoding.UTF8.GetString(msgResponse.Body); Console.WriteLine(string.Format("接收时间:{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody)); } //System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); } } } } } }
实际情况如下:

发送端接收端路由跟消息队列定义一致即可。
可以在管理页面查看实时情况

消费者端代码可以完善如下
//1-接收消息1 /*channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName); while (true) { BasicGetResult msgResponse = channel.BasicGet(QueueName, noAck: false); if (msgResponse != null) { var msgBody = Encoding.UTF8.GetString(msgResponse.Body); Console.WriteLine(string.Format("接收时间:{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody)); } //System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); }*/ /*但是这种处理速度较慢,因为循环线程等待。高效的接收消息的方式可以使用EventingBasicConsumer进行消息接收处理,修改代码内容如下:*/ //2-接收消息2 /*channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var msgBody = Encoding.UTF8.GetString(ea.Body); //接收msg处理业务 Console.WriteLine(string.Format("Customer接收时间:{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody)); }; channel.BasicConsume(QueueName,noAck:true,consumer:consumer); Console.WriteLine("按任意值,退出程序"); Console.ReadKey();*/ /* 但是有些时候,消费者同一时间没有能力处理太多的业务,导致分配过来的队列消息 不能及时处理完成,这个时候,我们可以设置BasicQos属性, 告诉Broker同一时间将未处理完成的消息分配其他消费者, 所以接收消息的地方需要略做修改,代码如下:*/ //3-接收消息3 channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.BasicQos(prefetchSize:0,prefetchCount:1,global:false);//告诉broker同一时间只处理一个消息 var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var msgBody = Encoding.UTF8.GetString(ea.Body); Console.WriteLine(string.Format("Customer接收时间:{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody)); int dots = msgBody.Split('.').Length - 1; System.Threading.Thread.Sleep(dots * 1000); Console.WriteLine(" [x] Done"); //处理完成,告诉Broker可以服务端可以删除消息,分配新的消息过来 channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); }; //noAck设置false,告诉broker,发送消息之后,消息暂时不要删除,等消费者处理完成再说 channel.BasicConsume(QueueName, noAck: false, consumer: consumer); Console.WriteLine("按任意值,退出程序"); Console.ReadKey();

浙公网安备 33010602011771号