.NET ActiveMQ类库
ActiveMQ .NET类库
ActiveMQ是一种开源的,实现了JMS规范的,面向消息(MOM)的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。
0. 准备
使用Nuget管理控制台安装最新版Apache.NMS.ActiveMQ
PM> Install-Package Apache.NMS.ActiveMQ
1. IMessageQueue 队列接口
/// <summary>
/// 消息队列接口
/// </summary>
public interface IMessageQueue
{
/// <summary>
/// 打开连接
/// </summary>
void Open();
/// <summary>
/// 关闭连接
/// </summary>
void Close();
}
2. ActiveMQ 抽象基类
/// <summary>
/// ActiveMQ
/// </summary>
public abstract class ActiveMQ
{
#region 监听连接对象
protected IConnection _connection;
protected ISession _session;
protected IMessageConsumer _consumer;
#endregion
/// <summary>
/// 连接地址
/// </summary>
public string BrokerUri { get; set; }
/// <summary>
/// 用于登录的用户名,必须和密码同时指定
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 用于登录的密码,必须和用户名同时指定
/// </summary>
public string Password { get; set; }
/// <summary>
/// 队列名称
/// </summary>
public string QueueName { get; set; }
/// <summary>
/// 指定使用队列的模式
/// </summary>
public MQMode MQMode { get; set; }
}
队列模式:
/// <summary>
/// 队列模式
/// </summary>
public enum MQMode
{
/// <summary>
/// 队列,点对点模式。
/// 使用此模式。一个生产者向队列存入一条消息之后,只有一个消费者能触发消息接收事件。
/// </summary>
Queue,
/// <summary>
/// 主题,发布者/订阅模式。
/// 使用此模式,一个生产者向队列存入一条消息之后,所有订阅当前的主题的消费者都能触发消息接收事件。
/// 使用此模式,必须先创建消费者,再创建生产者。
/// </summary>
Topic
}
3. ActiveMQProducer 生产者
/// <summary>
/// ActiveMQ生产者,打开连接,向指定队列中发送数据
/// </summary>
public class ActiveMQProducer : ActiveMQ, IMessageQueue, IDisposable
{
/// <summary>
/// 队列缓存字典
/// </summary>
private ConcurrentDictionary<string, IMessageProducer> _concrtProcuder = new ConcurrentDictionary<string, IMessageProducer>();
/// <summary>
/// 打开连接
/// </summary>
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);
}
/// <summary>
/// 关闭连接
/// </summary>
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();
}
/// <summary>
/// 向队列发送数据
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="body">数据</param>
public void Put<T>(T body)
{
Send(this.QueueName, body);
}
/// <summary>
/// 向指定队列发送数据
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="body">数据</param>
/// <param name="queueName">指定队列名</param>
public void Put<T>(T body, string queueName)
{
Send(queueName, body);
}
/// <summary>
/// 创建队列
/// </summary>
/// <param name="queueName"></param>
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);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="queueName">队列名称</param>
/// <typeparam name="T"></typeparam>
/// <param name="body">数据</param>
private void Send<T>(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);
}
}
/// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
this.Close();
}
}
4. ActiveMQConsumer 消费者
/// <summary>
/// ActiveMQ消费者,打开连接,监听队列,接收到数据之后触发回调
/// </summary>
public class ActiveMQConsumer : ActiveMQ, IMessageQueue, IDisposable
{
/// <summary>
/// 接收到数据回调,ActiveMQ原生IMessage类型
/// </summary>
public Action<IMessage> OnMessageReceived { get; set; }
/// <summary>
/// 接收到消息回调(业务数据对象, 根据自己的业务灵活替换)
/// </summary>
public Action<DataCenterMessage> OnDataCenterMessageReceived { get; set; }
/// <summary>
/// 打开连接
/// </summary>
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()));
}
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
_consumer?.Close();
_session?.Close();
_connection?.Close();
}
/// <summary>
/// 开始监听
/// </summary>
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);
}
}
}
});
}
/// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
this.Close();
}
}
5. 扩展方法
/// <summary>
/// 扩展方法类
/// </summary>
public static class ExtendMethods
{
/// <summary>
/// 将对象转换为bytes
/// </summary>
/// <param name="obj"></param>
/// <returns>bytes</returns>
public static byte[] ToBytes<T>(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();
}
}
/// <summary>
/// 将bytes转换为对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <returns></returns>
public static T ToObject<T>(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<DataCenterMessage>();
Debug.WriteLine(result);
}
};
consumer.OnDataCenterMessageReceived = (msg) =>
{
Debug.Write(msg);
};
consumer.Open();
consumer.StartListen();
.NET ActiveMQ类库的更多相关文章
- C# ACtiveMQ 收发数据
1.下载ActiveMQ 官方网站下载地址:http://activemq.apache.org/ 2.运行ActiveMQ 解压缩apache-activemq-5.10.0-bin.zip,然后双 ...
- ActiveMQ客户端Apache.NMS从.net 4.0移植到.net standard 2.0
1.从官网或GitHub下载Apache.NMS源码 2.新建.net standard 2.0类库 3.将源码复制到新建的类库中,并删除或注释CommonAssemblyInfo.cs文件(程序集版 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。附:网友制作的类库说明(CHM)
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- SignalR与ActiveMQ结合构建实时通信
一.概述 本教程主要阐释了如何利用SignalR与消息队列的结合,实现不同客户端的交互 SignalR如何和消息队列交互(暂使用ActiveMQ消息队列) SignalR寄宿在web中和其他Signa ...
- ActiveMQ基本配置与示例演示
一.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 二.运行ActiveMQ 将apache-activemq-5.11.1-bin.zip解压,由于本系 ...
- tomcat下部署activemq(转)
转自:http://marshal.easymorse.com/archives/1414 activemq可以单独部署和执行,比如类似ActiveMQ的最简单应用中提到的安装和执行方式.但是有时候需 ...
- SignalR与ActiveMQ
SignalR与ActiveMQ结合构建实时通信 一.概述 本教程主要阐释了如何利用SignalR与消息队列的结合,实现不同客户端的交互 SignalR如何和消息队列交互(暂使用ActiveMQ消 ...
- ActiveMQ笔记:一个高稳定,可扩展的的部署方案
本文介绍一个笔者在实际工作中的实施的基于ActiveMQ的一个高稳定,可扩展的异步消息系统. ActiveMQ是一个成熟的基于Java语言的开源消息系统,在实际应用中被大量使用.ActiveMQ在系统 ...
- activemq+Zookeper高可用集群方案配置
在高并发.对稳定性要求极高的系统中,高可用的是必不可少的,当然ActiveMQ也有自己的集群方案.从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式 ...
随机推荐
- easywechat (在thinkphp5中使用easywechat完成微信网页认证)
由于在easywechat中没有提及在thinkphp中的使用,后来我在http://www.thinkphp.cn/topic/45416.html中找到了有人已经封装了一下,我把自己使用的过程写下 ...
- Lucene入门学习
技术原理: 开发环境: lucene包:分词包,核心包,高亮显示(highlight和memory),查询包.(下载请到官网去查看,如若下载其他版本,请看我的上篇文档,在luke里面) 原文文档: 入 ...
- lucene学习教程
1Lucene的介绍 ①Lucene是什么: 是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎 ②Lu ...
- day16 十六、包、循环导入、导入模块
一.包的概念 包:一系列模块的集合体.包通过文件夹管理一系列功能相近的模块 重点:包中一定有一个专门用来管理包中所有模块的文件 包名:存放一系列模块的文件夹的名字 包名(对象)存放的是管理模块的那个文 ...
- 倒计时48小时|2018GIAC上海站参会攻略来了!
再过一天,令大家期待已久的GIAC全球互联网架构大会将登陆魔都与众位架构师.技术负责人及高端技术从业人员见面! 这场策划许久的技术盛宴,我们邀请到了腾讯.阿里.京东.美团.keep.UC.360.网商 ...
- liunx系统问题总结
1.Unable to locate package错误 解决办法 :输入命令 sudo apt-get update,进行软件的更新
- 项目实战03:Keepalived 实现高可用
目录 实验一:实现keepalived主从方式高可用基于LVS-DR模式的应用实战: 1.环境准备: 2.在lvs-server-master 主上 3.在lvs-server-backup 从上 4 ...
- linux命令: 两个查找工具 locate,find
linux 中有很多查找工具,今天主要讲解locate,find两个工具. 1.locate (1)查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db 注意:如果这 ...
- centos7编译安装Python3所需要的库(模块)依赖
在centos中编译安装python3环境,第三方的库 实战的编辑环境: 1.VMware虚拟机 2.centos7 依赖包经过百度搜集以及之前安装Python3报错搜集(centos7反反复复安 ...
- xutils android studio引用问题
然后rebuild--->关闭项目-->重启,ok public class MyApplication extends Application { @Override public vo ...