RabbitMQ.Client .NET 简单使用
生产者
static void Main(string[] args) { new Producer(); } public class Producer { //交换机名字 private static string exchange_name = "direct_test"; public Producer() { //创建连接工厂并设置连接信息,这些连接信息都是默认的,所以这里注释掉了,打开也是可以的。 ConnectionFactory connectionFactory = new ConnectionFactory(); //connectionFactory.HostName = "localhost"; //connectionFactory.UserName = "guest"; //connectionFactory.Password = "guest"; //connectionFactory.Port = 5672; //Console.WriteLine($"HostName:{connectionFactory.HostName},UserName:{connectionFactory.UserName},Password:{connectionFactory.Password},Port:{connectionFactory.Port}"); //新建连接 var conection = connectionFactory.CreateConnection(); //新建信道 var channel = conection.CreateModel(); //交换机 Name:交换机名称。 Durable:消息代理重启后,交换机是否还存在。 Auto-delete :当所有与之绑定的消息队列都完成了对此交换机的使用后,删掉它。 Arguments:依赖代理本身。 channel.ExchangeDeclare(exchange: exchange_name, type: "direct", durable: true, autoDelete: false); //消息持久化。 var properties = channel.CreateBasicProperties(); properties.Persistent = true; properties.DeliveryMode = 2; string queuename = "test.queue"; //创建队列queue:队列名 durable:消息代理重启后,队列是否还存在 exclusive:只被一个连接使用,连接关闭后,将立即删除队列 Auto-delete:当所有的消费者都退订队列后将自动删除该队列 channel.QueueDeclare(queue: queuename, durable: true, exclusive: false, autoDelete: false); int i = 0; while (i <=1000) { Thread.Sleep(1000); string routingKey; if (i % 2 == 0) { routingKey = "int.queueKey"; } else { routingKey = "float.queueKey"; } //绑定队列 channel.QueueBind(queue: queuename, exchange: exchange_name, routingKey: routingKey); //发送消息 channel.BasicPublish(exchange_name, routingKey, properties, Encoding.UTF8.GetBytes($"{i} 个Bug")); Console.WriteLine($"SendMg-->不得了,发送Bug啦:{ i} 个Bug"); i++; } channel.Close(); conection.Close(); } }
消费者
static void Main(string[] args) { new Consumer1(); } public class Consumer1 { //交换机名字 private static string exchange_name = "direct_test"; public Consumer1(){ //创建连接工厂并设置连接信息,这些连接信息都是默认的,所以这里注释掉了,打开也是可以的。 ConnectionFactory connectionFactory = new ConnectionFactory(); //connectionFactory.HostName = "localhost"; //connectionFactory.UserName = "guest"; //connectionFactory.Password = "guest"; //connectionFactory.Port = 5672; Console.WriteLine($"Consumer1---- HostName:{connectionFactory.HostName},UserName:{connectionFactory.UserName},Password:{connectionFactory.Password}"); //新建连接 var conection = connectionFactory.CreateConnection(); //新建信道 var channel = conection.CreateModel(); //交换机 Name:交换机名称。 Durable:消息代理重启后,交换机是否还存在。 Auto-delete :当所有与之绑定的消息队列都完成了对此交换机的使用后,删掉它。 Arguments:依赖代理本身。 channel.ExchangeDeclare(exchange: exchange_name, type: "direct", durable: true, autoDelete: false); //声明队列 string queuename = string.Empty; string routingKey = string.Empty; queuename = "test.queue"; routingKey = "int.queueKey";
//虽然取的是这个路由的,但是最终结果是取到了该队列所有的消息,但是声明是新的队列(test.queue1)的话,取得就是路由 int.queueKey 对应的消息,
//但是原队列 test.queue的消息并没有被消费,这样下去不是会一直累加吗?很奇怪!!!!!
//routingKey = "float.queueKey";
//创建队列queue:队列名 durable:消息代理重启后,队列是否还存在 exclusive:只被一个连接使用,连接关闭后,将立即删除队列 Auto-delete:当所有的消费者都退订队列后将自动删除该队列
channel.QueueDeclare(queue: queuename, durable: true, exclusive: false, autoDelete: false);
//绑定队列
channel.QueueBind(queue: queuename, exchange: exchange_name, routingKey: routingKey);
//公平分发,不要同一时间给一个工作者发送多于一个消息
channel.BasicQos(0, 1, false);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) => {
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine("ReceiveMsg-->哦豁,接到Bug了 : {0}", message);
//手动发送确认消息
channel.BasicAck(ea.DeliveryTag, false);
};
//指定从哪个消费者从哪个通道获取消息,并指明自动确认的机制 //参数1:队列名,参数2:确认机制,true表示自动确认,false代表手动确认,参数3:消费者
string consumerTag = channel.BasicConsume(queuename, false, consumer); Console.ReadKey();
}
}
效果图:
留个问题 :
我消费消息的时候,取得是路由为 int.queueKey 的,但是可以看到 是test.queue这个队列的消息都消费了,,但是声明是新的队列(test.queue1)的话,取得就是路由 int.queueKey 对应的消息,但是原队列 test.queue的消息并没有被消费,这样下去不是会一直累加吗?很奇怪!!!!!欢迎大佬解答下。
https://www.cnblogs.com/wutianqi/p/10043011.html 可以学习下rabbitmq,这个博客写的比较详细点