usingRabbitMQ.Client;usingRabbitMQ.Client.Events;usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;usingRabbitMQ.Client.Exceptions;namespaceMQ_Receive
{///
///RabbitMq消息监听器///
public classRabbitMqListener
{privateConnectionFactory _factory;privateIConnection _con;privateIModel _channel;privateEventingBasicConsumer _consumer;private readonly string_rabbitMqUri;private readonly string_exchangeType;private readonly string_exchangeName;private readonly string_queueName;private readonly string_routeKey;private Func_messageHandler;///
///RabbitMQ消息监听器,若指定的队列不存在,则自动创建队列。并在消息交换机上绑定指定的消息路由规则(路由key)///
/// 连接串,如 amqp://guest:guest@localhost:5672/
/// 消息交换机
/// 交换机类型,如 ExchangeType.Direct
/// 要监听的队列
/// 消息路由key
public RabbitMqListener(string rabbitMqUri, string exchangeName, string exchangeType, string queueName, string routeKey = "")
{this._rabbitMqUri =rabbitMqUri;this._exchangeName =exchangeName;this._exchangeType =exchangeType;this._queueName =queueName;this._routeKey =routeKey;
}///
///创建连接///
private voidCreateConnection()
{
_factory= newConnectionFactory
{
Uri= newUri(_rabbitMqUri),
RequestedHeartbeat= 20,
AutomaticRecoveryEnabled= true,
TopologyRecoveryEnabled= true,
NetworkRecoveryInterval= TimeSpan.FromSeconds(10)
};
_con=_factory.CreateConnection();
_con.ConnectionShutdown+= (_sender, _e) => ReMessageListen();//掉线重新连接并监听队列消息
}///
///创建信道///
private voidCreateChannel()
{
_channel=_con.CreateModel();
_channel.ExchangeDeclare(_exchangeName, _exchangeType,true, false, null);
_channel.QueueDeclare(_queueName,true, false, false, null); //创建一个消息队列,用来存储消息
_channel.QueueBind(_queueName, _exchangeName, _routeKey, null);
_channel.BasicQos(0, 3, true); //在非自动确认消息的前提下,如果一定数目的消息(通过基于consume或者channel设置Qos的值)未被确认前,不进行消费新的消息
}///
///监听队列消息///
/// 消息处理器,当监测到队列消息时回调该处理器
/// 监听状态
public bool MessageListen(FuncmessageHandler)
{try{this.CreateConnection();this.CreateChannel();
_consumer= new EventingBasicConsumer(_channel); //基于事件的消息推送方式
_consumer.Received += (_sender, _e) =>{string msg =Encoding.UTF8.GetString(_e.Body);if (messageHandler != null)
{this._messageHandler =messageHandler;try{var isOk = this._messageHandler(msg);if(isOk)
{
_channel.BasicAck(_e.DeliveryTag,false);
}
}catch(Exception ex)
{
LoggerManager.ErrorLog.Error("消息处理器执行异常:" +ex.Message, ex);
}
}
};
_channel.BasicConsume(_queueName,false, _consumer); //手动确认
return true;
}catch(Exception ex)
{
LoggerManager.ErrorLog.Error("尝试监听队列消息出现错误:" +ex.Message, ex);
}return false;
}public voidReMessageListen()
{try{//清除连接及频道
CleanupResource();var mres = new ManualResetEventSlim(false); //初始化状态为false
while (!mres.Wait(3000)) //每3秒监测一次状态,直到状态为true
{if(MessageListen(_messageHandler))
{
mres.Set();//设置状态为true并跳出循环
}
}
}catch(Exception ex)
{
LoggerManager.ErrorLog.Error("尝试连接RabbitMQ服务器出现错误:" +ex.Message, ex);
}
}///
///清理资源///
private voidCleanupResource()
{if (_channel != null &&_channel.IsOpen)
{try{
_channel.Close();
}catch(Exception ex)
{
LoggerManager.ErrorLog.Error("尝试关闭RabbitMQ信道遇到错误", ex);
}
_channel= null;
}if (_con != null &&_con.IsOpen)
{try{
_con.Close();
}catch(Exception ex)
{
LoggerManager.ErrorLog.Error("尝试关闭RabbitMQ连接遇到错误", ex);
}
_con= null;
}
}
}
}