Rabbit MQ 实例(.NET)
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using log4net;
namespace Vcredit.RC.Helper.RabbitMQ
{
public class RabbitMqConfig
{
public string Ip { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int Port { get; set; }
public string VirtualHost { get; set; }
public string QueueName { get; set; }
public string ExchangeName { get; set; }
public string ExchangeType { get; set; }
public string RoutingKey { get; set; }
public ushort PrefetchCount { get; set; }
public bool DurableQueue { get; set; }
public bool DurableMessage { get; set; }
public IDictionary<string, object> Headers { get; set; }
public IDictionary<string, object> Arguments { get; set; }
}
public enum ProcessingResultsEnum
{
Accept,
Retry,
Reject,
}
public class MessageQueueSerice
{
#region 字段
public static IConnection _connection;
private static ILog _logger = LogManager.GetLogger(typeof(RedisHelper));
#endregion
#region 构造函数
public MessageQueueSerice(RabbitMqConfig RabbitConfig)
{
try
{
CreateConn(RabbitConfig);
}
catch (Exception)
{
throw;
}
}
#endregion
#region 初始化
public void CreateConn(RabbitMqConfig RabbitConfig)
{
ConnectionFactory cf = new ConnectionFactory();
cf.Port = RabbitConfig.Port;
cf.Endpoint = new AmqpTcpEndpoint(new Uri("amqp://" + RabbitConfig.Ip + "/"));
cf.UserName = RabbitConfig.UserName;
cf.Password = RabbitConfig.Password;
cf.VirtualHost = RabbitConfig.VirtualHost;
cf.RequestedHeartbeat = 60;
_connection = cf.CreateConnection();
}
#endregion
#region 方法
#region 发送消息
public bool Send<T>(T messageInfo, ref string errMsg, RabbitMqConfig RabbitConfig)
{
if (messageInfo == null)
{
errMsg = "消息对象不能为空";
return false;
}
string value = JsonConvert.SerializeObject(messageInfo);
return Send(value, ref errMsg, RabbitConfig);
}
public bool Send(string message, ref string errMsg, RabbitMqConfig RabbitConfig)
{
if (string.IsNullOrEmpty(message))
{
errMsg = "消息不能为空";
return false;
}
try
{
if (!_connection.IsOpen)
{
CreateConn(RabbitConfig);
}
using (var channel = _connection.CreateModel())
{
byte[] bytes = Encoding.UTF8.GetBytes(message);
IBasicProperties properties = channel.CreateBasicProperties();
properties.DeliveryMode = Convert.ToByte(RabbitConfig.DurableMessage ? 2 : 1);
if (RabbitConfig.Headers != null)
{
properties.Headers = RabbitConfig.Headers;
}
channel.ExchangeDeclare(RabbitConfig.ExchangeName, RabbitConfig.ExchangeType.ToString(), RabbitConfig.DurableQueue, false, null);
channel.QueueDeclare(RabbitConfig.QueueName, RabbitConfig.DurableQueue, false, false, RabbitConfig.Arguments);
channel.QueueBind(RabbitConfig.QueueName, RabbitConfig.ExchangeName, RabbitConfig.RoutingKey, null);
channel.BasicPublish(RabbitConfig.ExchangeName, RabbitConfig.RoutingKey, properties, bytes);
return true;
}
}
catch (Exception ex)
{
errMsg = ex.Message;
return false;
}
}
#endregion
#region 接受消息,使用Func进行处理
public void Receive<T>(Func<T, IDictionary<string, object>, bool> method, RabbitMqConfig RabbitConfig)
{
try
{
using (var channel = _connection.CreateModel())
{
#region 绑定队列和交换机
channel.ExchangeDeclare(RabbitConfig.ExchangeName, RabbitConfig.ExchangeType.ToString(), RabbitConfig.DurableQueue, false, null);
channel.QueueDeclare(RabbitConfig.QueueName, RabbitConfig.DurableQueue, false, false, RabbitConfig.Arguments);
channel.QueueBind(RabbitConfig.QueueName, RabbitConfig.ExchangeName, RabbitConfig.RoutingKey, null);
#endregion
#region 业务
channel.BasicQos(0, RabbitConfig.PrefetchCount, false);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
ProcessingResultsEnum processingResult = ProcessingResultsEnum.Retry;
ulong deliveryTag = 0;
try
{
deliveryTag = ea.DeliveryTag;
byte[] bytes = ea.Body;
string body = Encoding.UTF8.GetString(bytes);
T info = JsonConvert.DeserializeObject<T>(body);
bool r = method(info, ea.BasicProperties.Headers);
processingResult = r ? ProcessingResultsEnum.Accept : ProcessingResultsEnum.Retry;
}
catch (Exception ex)
{
processingResult = ProcessingResultsEnum.Reject;
_logger.Error("RabbitMq消息处理异常", ex);
}
finally
{
switch (processingResult)
{
case ProcessingResultsEnum.Accept:
channel.BasicAck(deliveryTag,
false);
break;
case ProcessingResultsEnum.Retry:
channel.BasicNack(deliveryTag, false, true);
break;
case ProcessingResultsEnum.Reject:
channel.BasicNack(deliveryTag, false, false);
break;
}
}
};
channel.BasicConsume(RabbitConfig.QueueName,
false,
consumer);
System.Threading.Thread.Sleep(-1);
}
#endregion
}
catch (Exception ex)
{
_logger.Error("RabbitMq获取消息异常", ex);
}
}
#endregion
#endregion
}
}