版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fanbin168/article/details/89358579
消息不可达
项目需要先启动消费端,再启动生产端
生产端
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProducterApp
{
class Program
{
/// 连接配置
/// </summary>
private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory() //创建一个工厂连接对象
{
HostName = "192.168.31.30",
UserName = "admin",
Password = "admin",
VirtualHost = "/vhost001", //如果不设置,虚拟主机名称路径默认为 /
Port = 5672, //注意:5672 --是client端通信口 15672 -- 是管理界面ui端口
AutomaticRecoveryEnabled = true,//网络故障自动连接恢复
};
/// <summary>
/// 路由名称
/// </summary>
const string ExchangeName = "exchange999";
const string routingKey = "routing.return999";
//队列名称
//const string QueueName = "queue010";
static void Main(string[] args)
{
using (IConnection conn = rabbitMqFactory.CreateConnection()) //创建一个连接
{
using (IModel channel = conn.CreateModel()) //创建一个Channel
{
IBasicProperties props = channel.CreateBasicProperties();
props.DeliveryMode = 2; //1:非持久化 2:持续久化 (即:当值为2的时候,我们一个消息发送到服务器上之后,如果消息还没有被消费者消费,服务器重启了之后,这条消息依然存在)
props.Persistent = true;
props.ContentEncoding = "UTF-8"; //注意要大写
//props.Expiration = "250000"; //消息过期时间为25秒
//这个事件就是用来监听我们一些不可达的消息的(比如)
EventHandler<BasicReturnEventArgs> evreturn = new EventHandler<BasicReturnEventArgs>((o, b) => {
Console.WriteLine(b.ReplyCode); //消息失败的code
Console.WriteLine(b.ReplyText);
Console.WriteLine(Encoding.UTF8.GetString(b.Body)); //失败消息的内容
});
channel.BasicReturn += evreturn;
//我们也可以设定自定义属性,把自定义的属性放到Headers中进行发送
var dir = new Dictionary<string, object>();
dir.Add("name", "张三");//特别要注意,字符串传递过去的时候是实际是以byte[]数组的形式传递过去的
dir.Add("age", 25);
props.Headers = dir;
for (int i = 0; i < 5; i++)
{
props.MessageId = Guid.NewGuid().ToString("N"); //设定这条消息的MessageId(每条消息的MessageId都是唯一的)
string msg = "你好,这是我的第" + i + "条消息;时间:" + DateTime.Now.ToString("yyyy:MM:dd");
var msgBody = Encoding.UTF8.GetBytes(msg); //发送的消息必须是二进制的
channel.BasicPublish(exchange: ExchangeName, routingKey: routingKey, mandatory:true, basicProperties: props, body: msgBody);
}
Console.ReadKey();
}
}
}
}
}
消费端
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
namespace CustomerApp
{
class Program
{
/// <summary>
/// 连接配置
/// </summary>
private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory()
{
HostName = "192.168.31.30",
UserName = "admin",
Password = "admin",
Port = 5672,
VirtualHost = "/vhost001",
};
/// <summary>
/// 路由名称
/// </summary>
const string ExchangeName = "exchange999";
//队列名称
const string QueueName = "queue999";
const string routingKey = "routing-return"; //这里routingkey与消费端的routingkey不保持一致的原因就是要测试生产端的消息不可达,测试不可达所产生的事件调用
static void Main(string[] args)
{
using (IConnection conn = rabbitMqFactory.CreateConnection())
{
using (IModel channel = conn.CreateModel())
{
channel.ExchangeDeclare(ExchangeName, "topic", durable: true, autoDelete: false, arguments: null);
channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
channel.QueueBind(QueueName, ExchangeName, routingKey: routingKey);
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);//告诉broker同一时间只处理一个消息
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
while (true)
{
consumer.Received += (model, ea) =>
{
var msgBody = Encoding.UTF8.GetString(ea.Body);
Console.WriteLine(string.Format("接收时间:{0},消息内容:{1}", DateTime.Now.ToString("HH:mm:ss"), msgBody));
//处理完成,告诉Broker可以服务端可以删除消息,分配新的消息过来
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
//noAck设置false,告诉broker,发送消息之后,消息暂时不要删除,等消费者处理完成再说
channel.BasicConsume(QueueName, autoAck: false, consumer: consumer);
}
}
}
}
}
}