.NET ActiveMQ类库

ActiveMQ .NET类库

ActiveMQ是一种开源的,实现了JMS规范的,面向消息(MOM)的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。

0. 准备

使用Nuget管理控制台安装最新版Apache.NMS.ActiveMQ

PM> Install-Package Apache.NMS.ActiveMQ

1. IMessageQueue 队列接口

///


/// 消息队列接口
///

public interface IMessageQueue
{

///


/// 打开连接
///

void Open();

///


/// 关闭连接
///

void Close();
}

2. ActiveMQ 抽象基类

///


/// ActiveMQ
///

public abstract class ActiveMQ
{
#region 监听连接对象
protected IConnection _connection;
protected ISession _session;
protected IMessageConsumer _consumer;
#endregion

///


/// 连接地址
///

public string BrokerUri { get; set; }

///


/// 用于登录的用户名,必须和密码同时指定
///

public string UserName { get; set; }

///


/// 用于登录的密码,必须和用户名同时指定
///

public string Password { get; set; }

///


/// 队列名称
///

public string QueueName { get; set; }

///


/// 指定使用队列的模式
///

public MQMode MQMode { get; set; }
}
队列模式:

///


/// 队列模式
///

public enum MQMode
{
///
/// 队列,点对点模式。
/// 使用此模式。一个生产者向队列存入一条消息之后,只有一个消费者能触发消息接收事件。
///

Queue,

///


/// 主题,发布者/订阅模式。
/// 使用此模式,一个生产者向队列存入一条消息之后,所有订阅当前的主题的消费者都能触发消息接收事件。
/// 使用此模式,必须先创建消费者,再创建生产者。
///

Topic
}

3. ActiveMQProducer 生产者

///


/// ActiveMQ生产者,打开连接,向指定队列中发送数据
///

public class ActiveMQProducer : ActiveMQ, IMessageQueue, IDisposable
{
///
/// 队列缓存字典
///

private ConcurrentDictionary<string, IMessageProducer> _concrtProcuder = new ConcurrentDictionary<string, IMessageProducer>();

///


/// 打开连接
///

public void Open()
{
if (string.IsNullOrWhiteSpace(this.BrokerUri))
throw new MemberAccessException("未指定BrokerUri");
if (string.IsNullOrWhiteSpace(this.QueueName))
throw new MemberAccessException("未指定QueueName");

var factory = new ConnectionFactory(this.BrokerUri);
if (string.IsNullOrWhiteSpace(this.UserName) && string.IsNullOrWhiteSpace(this.Password))
_connection = factory.CreateConnection();
else
_connection = factory.CreateConnection(this.UserName, this.Password);
_connection.Start();
_session = _connection.CreateSession();

CreateProducer(this.QueueName);
}

///


/// 关闭连接
///

public void Close()
{
IMessageProducer _p = null;
foreach (var p in this._concrtProcuder)
{
if (this._concrtProcuder.TryGetValue(p.Key, out _p))
{
_p?.Close();
}
}
this._concrtProcuder.Clear();

_session?.Close();
_connection?.Close();
}

///


/// 向队列发送数据
///

/// 数据类型
/// 数据
public void Put(T body)
{
Send(this.QueueName, body);
}

///


/// 向指定队列发送数据
///

/// 数据类型
/// 数据
/// 指定队列名
public void Put(T body, string queueName)
{
Send(queueName, body);
}

///


/// 创建队列
///

///
private IMessageProducer CreateProducer(string queueName)
{
if (_session == null)
{
Open();
}

//创建新生产者
Func<string, IMessageProducer> CreateNewProducter = (name) =>
{
IMessageProducer _newProducer = null;
switch (MQMode)
{
case MQMode.Queue:
{
_newProducer = _session.CreateProducer(new ActiveMQQueue(name));
break;
}
case MQMode.Topic:
{
_newProducer = _session.CreateProducer(new ActiveMQTopic(name));
break;
}
default:
{
throw new Exception(string.Format("无法识别的MQMode类型:{0}", MQMode.ToString()));
}
}
return _newProducer;
};

return this._concrtProcuder.GetOrAdd(queueName, CreateNewProducter);
}

///


/// 发送数据
///

/// 队列名称
///
/// 数据
private void Send(string queueName, T body)
{
var producer = CreateProducer(queueName);
IMessage msg;
if (body is byte[])
{
msg = producer.CreateBytesMessage(body as byte[]);
}
else if (body is string)
{
msg = producer.CreateTextMessage(body as string);
}
else
{
msg = producer.CreateObjectMessage(body);
}
if (msg != null)
{
producer.Send(msg, MsgDeliveryMode.Persistent, MsgPriority.Normal, TimeSpan.MinValue);
}
}

///


/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
///

public void Dispose()
{
this.Close();
}
}

4. ActiveMQConsumer 消费者

///


/// ActiveMQ消费者,打开连接,监听队列,接收到数据之后触发回调
///

public class ActiveMQConsumer : ActiveMQ, IMessageQueue, IDisposable
{
///
/// 接收到数据回调,ActiveMQ原生IMessage类型
///

public Action OnMessageReceived { get; set; }

///


/// 接收到消息回调(业务数据对象, 根据自己的业务灵活替换)
///

public Action OnDataCenterMessageReceived { get; set; }

///


/// 打开连接
///

public void Open()
{
if (string.IsNullOrWhiteSpace(this.BrokerUri))
throw new MemberAccessException("未指定BrokerUri");
if (string.IsNullOrWhiteSpace(this.QueueName))
throw new MemberAccessException("未指定QueueName");

var factory = new ConnectionFactory(this.BrokerUri);
if (string.IsNullOrWhiteSpace(this.UserName) && string.IsNullOrWhiteSpace(this.Password))
_connection = factory.CreateConnection();
else
_connection = factory.CreateConnection(this.UserName, this.Password);
_connection.Start();
_session = _connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

switch (MQMode)
{
case MQMode.Queue:
{
_consumer = _session.CreateConsumer(new ActiveMQQueue(this.QueueName));
break;
}
case MQMode.Topic:
{
_consumer = _session.CreateConsumer(new ActiveMQTopic(this.QueueName));
break;
}
default:
{
throw new Exception(string.Format("无法识别的MQMode类型:{0}", MQMode.ToString()));
}
}
}

///


/// 关闭连接
///

public void Close()
{
_consumer?.Close();
_session?.Close();
_connection?.Close();
}

///


/// 开始监听
///

public void StartListen()
{
if (_consumer == null)
{
Open();
}

_consumer.Listener += new MessageListener(msg =>
{
if (OnMessageReceived != null)
OnMessageReceived(msg);

//转换为业务需要的数据对象
if (OnDataCenterMessageReceived != null)
{
var objectMessage = msg as ActiveMQObjectMessage;
if (objectMessage != null)
{
var dataCenterMsg = objectMessage.Body as DataCenterMessage;
if (dataCenterMsg != null)
{
OnDataCenterMessageReceived(dataCenterMsg);
}
}
}
});
}

///


/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
///

public void Dispose()
{
this.Close();
}
}

5. 扩展方法

///


/// 扩展方法类
///

public static class ExtendMethods
{
///
/// 将对象转换为bytes
///

///
/// bytes
public static byte[] ToBytes(this T obj) where T : class
{
if (obj == null)
return null;
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
return ms.GetBuffer();
}
}

///


/// 将bytes转换为对象
///

///
///
///
public static T ToObject(this byte[] bytes) where T : class
{
if (bytes == null)
return default(T);
using (var ms = new MemoryStream(bytes))
{
var formatter = new BinaryFormatter();
return formatter.Deserialize(ms) as T;
}
}
}

6. 使用示例:

region 生产者

var producer = new ActiveMQProducer();
producer.BrokerUri = @"tcp://127.0.0.1:61616/";
producer.UserName = "admin";
producer.Password = "admin";
producer.QueueName = "TestQueueName";
producer.MQMode = MQMode.Queue;

producer.Open();
var message = new DataCenterMessage()
{
//初始化业务数据对象...
};

//发送到队列, Put对象类必须使用[Serializable]注解属性
producer.Put(message);
#endregion

region 消费者

var consumer = new ActiveMQConsumer();
consumer.BrokerUri = @"tcp://127.0.0.1:61616/";
consumer.UserName = "admin";
consumer.Password = "admin";
consumer.QueueName = "TestQueueName";
consumer.MQMode = MQMode.Queue;

consumer.OnMessageReceived = (msg) =>
{
var bytesMessage = msg as ActiveMQBytesMessage;
if (bytesMessage != null)
{
var buffer = new byte[bytesMessage.BodyLength];
bytesMessage.WriteBytes(buffer);
var result = buffer.ToObject();
Debug.WriteLine(result);
}
};

consumer.OnDataCenterMessageReceived = (msg) =>
{
Debug.Write(msg);
};

consumer.Open();
consumer.StartListen();

posted @ 2017-10-13 10:47  A_ning  阅读(2910)  评论(5)    收藏  举报