一、项目创建
VS2017创建.Net项目,项目创建完成后,从Nuget搜索并安装Apache.NMS.ActiveMQ
二、消息发布及订阅方法实现
消息发布
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using Apache.NMS.ActiveMQ.Commands;
namespace ActiveMqDemo
{
/// <summary>
/// ActiveMq消息发布
/// </summary>
public class ProduceWarpper
{
private IConnectionFactory _factory = null;
private IConnection _connection = null;
private ISession _session = null;
private readonly ConcurrentDictionary<string, IMessageProducer> _dic = null;
const string queuePrefix = "My.Quee.";//queue消息队列名称默认前缀 My.Quee.
const string topicPrefix = "My.Topic.";//topic消息队列名称默认前缀 My.Topic.
/// <summary>
/// 构造函数
/// </summary>
public ProduceWarpper()
{
_dic = new ConcurrentDictionary<string, IMessageProducer>();
}
/// <summary>
/// 打开连接
/// </summary>
public void Open()
{
Open("failover:(tcp://127.0.0.1:61616)?wireFormat.maxInactivityDuration=0&transport.timeout=3000&transport.startupMaxReconnectAttempts=2", "admin", "mypassword");
}
/// <summary>
/// 打开连接
/// </summary>
/// <param name="brokerUri">ip地址</param>
public void Open(string brokerUri)
{
Open(brokerUri, null, null);
}
/// <summary>
/// 打开连接
/// </summary>
/// <param name="brokerUri">ip地址</param>
/// <param name="username">用户名</param>
/// <param name="pwd">密码</param>
public void Open(string brokerUri, string username, string pwd)
{
bool flag = _factory != null;
if (!flag)
{
_factory = new ConnectionFactory(brokerUri);
bool flag2 = string.IsNullOrEmpty(username) || string.IsNullOrEmpty(pwd);
if (flag2)
{
_connection = _factory.CreateConnection();
}
else
{
_connection = _factory.CreateConnection(username, pwd);
}
_connection.ClientId = Guid.NewGuid().ToString();
_connection.ExceptionListener += new ExceptionListener(Connection_ExceptionListener);
_connection.Start();
_session = _connection.CreateSession();
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
bool flag = _dic.Any();
if (flag)
{
foreach (KeyValuePair<string, IMessageProducer> keyValuePair in _dic)
{
bool flag2 = keyValuePair.Value == null;
if (!flag2)
{
IMessageProducer value = keyValuePair.Value;
value.Close();
value.Dispose();
}
}
}
bool flag3 = _session != null;
if (flag3)
{
_session.Close();
_session.Dispose();
_session = null;
}
bool flag4 = _connection != null;
if (flag4)
{
_connection.Close();
_connection.Dispose();
_connection = null;
}
_factory = null;
}
/// <summary>
/// 发布Topic消息
/// </summary>
/// <param name="topicName">Topic名称</param>
/// <param name="msg">Topic内容</param>
public void ProduceTopicMsg(string topicName, string msg)
{
string finalKey = topicPrefix + topicName;
IDestination destination = new ActiveMQTopic(finalKey);
ProduceMsg(finalKey, msg, destination, TimeSpan.MinValue);
}
/// <summary>
/// 发布Queue消息
/// </summary>
/// <param name="queueName">Queue名称</param>
/// <param name="msg">Queue内容</param>
public void ProduceQueueMsg(string queueName, string msg)
{
string finalKey =queuePrefix+queueName;
IDestination destination = new ActiveMQQueue(finalKey);
ProduceMsg(finalKey, msg, destination, TimeSpan.MinValue);
}
/// <summary>
/// 发布消息
/// </summary>
/// <param name="key">Queue/Topic名称</param>
/// <param name="msg">消息内容</param>
/// <param name="destination"></param>
/// <param name="timeToLive"></param>
private void ProduceMsg(string key, string msg, IDestination destination, TimeSpan timeToLive)
{
bool flag = _factory == null;
if (flag)
{
throw new Exception("未调用open()方法");
}
IMessageProducer messageProducer = null;
bool flag2 = !_dic.TryGetValue(key, out messageProducer);
if (flag2)
{
messageProducer = _session.CreateProducer(destination);
_dic.TryAdd(key, messageProducer);
}
bool flag3 = messageProducer != null;
if (flag3)
{
messageProducer.Send(messageProducer.CreateTextMessage(msg), 0, MsgPriority.Normal, timeToLive);
}
}
/// <summary>
/// 连接错误信息
/// </summary>
/// <param name="exception"></param>
private void Connection_ExceptionListener(Exception exception)
{
string errMsg = string.Format("connection_ExceptionListener Error:{0}\r\n{1}", new object[]
{
exception.Message,
exception.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag = exception.InnerException != null;
if (flag)
{
WriteException(exception.InnerException);
}
}
/// <summary>
/// 错误日志
/// </summary>
/// <param name="exception"></param>
private void WriteException(Exception exception)
{
string errMsg = string.Format("{0}\r\n{1}", new object[]
{
exception.Message,
exception.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag = exception.InnerException != null;
if (flag)
{
WriteException(exception.InnerException);
}
}
}
}
消息订阅
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using Apache.NMS.ActiveMQ.Commands;
namespace ActiveMqDemo
{
/// <summary>
/// ActiveMq 消息订阅
/// </summary>
public class ConsumeWarpper
{
private IConnectionFactory _factory = null;
private IConnection _connection = null;
private ISession _session = null;
private readonly ConcurrentDictionary<string, DataModel> _dic = null;
const string queuePrefix = "My.Quee.";//queue消息队列名称默认前缀
const string topicPrefix = "My.Topic.";//topic消息队列名称默认前缀
/// <summary>
///
/// </summary>
private class DataModel
{
public IMessageConsumer Consumer { get; set; }
public List<Action<string>> Listeners { get; set; }
}
/// <summary>
/// 构造函数
/// </summary>
public ConsumeWarpper()
{
_dic = new ConcurrentDictionary<string, DataModel>();
}
/// <summary>
/// 打开连接
/// </summary>
public void Open()
{
Open("failover:(tcp://127.0.0.1:61616)?wireFormat.maxInactivityDuration=0&transport.timeout=3000&transport.startupMaxReconnectAttempts=2", "admin", "mypassword");
}
/// <summary>
/// 打开连接
/// </summary>
/// <param name="brokerUri">ip</param>
public void Open(string brokerUri)
{
Open(brokerUri, null, null);
}
/// <summary>
/// 打开连接
/// </summary>
/// <param name="brokerUri">ip</param>
/// <param name="username">用户名</param>
/// <param name="pwd">密码</param>
public void Open(string brokerUri, string username, string pwd)
{
bool flag = _factory != null;
if (!flag)
{
_factory = new ConnectionFactory(brokerUri);
bool flag2 = string.IsNullOrEmpty(username) || string.IsNullOrEmpty(pwd);
if (flag2)
{
_connection = _factory.CreateConnection();
}
else
{
_connection = _factory.CreateConnection(username, pwd);
}
_connection.ClientId = Guid.NewGuid().ToString();
_connection.ExceptionListener += new ExceptionListener(Connection_ExceptionListener);
_connection.Start();
_session = _connection.CreateSession();
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
bool flag = _dic.Any();
if (flag)
{
foreach (KeyValuePair<string, DataModel> keyValuePair in _dic)
{
bool flag2 = keyValuePair.Value == null;
if (!flag2)
{
IMessageConsumer consumer = keyValuePair.Value.Consumer;
consumer.Listener -= new MessageListener(consumer_Listener);
consumer.Close();
consumer.Dispose();
}
}
}
bool flag3 = _session != null;
if (flag3)
{
_session.Close();
_session.Dispose();
_session = null;
}
bool flag4 = _connection != null;
if (flag4)
{
_connection.Close();
_connection.Dispose();
_connection = null;
}
_factory = null;
}
/// <summary>
/// 订阅Topic消息
/// </summary>
/// <param name="topicName">Topic名称</param>
/// <param name="listener">订阅事件</param>
public void ConsumeTopicMsg(string topicName, Action<string> listener)
{
string finalKey = topicPrefix + topicName;
IDestination destination = new ActiveMQTopic(finalKey);
ConsumeMsg(finalKey, destination, listener);
}
/// <summary>
/// 订阅Queue消息
/// </summary>
/// <param name="queueName">Queue名称</param>
/// <param name="listener">订阅事件</param>
public void ConsumeQueueMsg(string queueName, Action<string> listener)
{
string finalKey = queuePrefix + queueName;
IDestination destination = new ActiveMQQueue(finalKey);
ConsumeMsg(finalKey, destination, listener);
}
/// <summary>
/// 消息订阅
/// </summary>
/// <param name="key"></param>
/// <param name="destination"></param>
/// <param name="listener"></param>
private void ConsumeMsg(string key, IDestination destination, Action<string> listener)
{
DataModel dataModel = null;
bool flag = _dic.TryGetValue(key, out dataModel);
if (flag)
{
dataModel.Listeners.Add(listener);
}
else
{
bool flag2 = _factory == null;
if (flag2)
{
throw new Exception("未调用open()方法");
}
IMessageConsumer messageConsumer = _session.CreateConsumer(destination);
messageConsumer.Listener += new MessageListener(consumer_Listener);
dataModel = new DataModel
{
Consumer = messageConsumer,
Listeners = new List<Action<string>>
{
listener
}
};
_dic.TryAdd(key, dataModel);
}
}
/// <summary>
/// 消息订阅监听事件
/// </summary>
/// <param name="message"></param>
private void consumer_Listener(IMessage message)
{
try
{
ITextMessage textMessage = message as ITextMessage;
bool flag = textMessage == null;
if (flag)
{
LogHelper.WriteTextLog("Error", "consumer_Listener: textMessage == null");
}
else
{
string key = "";
IDestination nmsdestination = message.NMSDestination;
bool isTopic = nmsdestination.IsTopic;
if (isTopic)
{
key = ((ActiveMQTopic)nmsdestination).TopicName;
}
else
{
bool isQueue = nmsdestination.IsQueue;
if (isQueue)
{
key = ((ActiveMQQueue)nmsdestination).QueueName;
}
}
DataModel dataModel = null;
bool flag2 = _dic.TryGetValue(key, out dataModel)&&dataModel.Listeners.Any();
if (flag2)
{
dataModel.Listeners.ForEach(delegate (Action<string> listener)
{
try
{
listener(textMessage.Text);
}
catch (Exception ex2)
{
string errMsg = string.Format("consumer_Listener Action Error:{0}\r\n{1}", new object[]
{
ex2.Message,
ex2.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag4 = ex2.InnerException != null;
if (flag4)
{
WriteException(ex2.InnerException);
}
}
});
}
}
}
catch (Exception ex)
{
string errMsg = string.Format("consumer_Listener Error:{0}\r\n{1}", new object[]
{
ex.Message,
ex.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag3 = ex.InnerException != null;
if (flag3)
{
WriteException(ex.InnerException);
}
}
}
/// <summary>
/// 连接错误日志
/// </summary>
/// <param name="exception"></param>
private void Connection_ExceptionListener(Exception exception)
{
string errMsg = string.Format("connection_ExceptionListener Error:{0}\r\n{1}", new object[]
{
exception.Message,
exception.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag = exception.InnerException != null;
if (flag)
{
WriteException(exception.InnerException);
}
}
/// <summary>
/// 错误日志
/// </summary>
/// <param name="exception"></param>
private void WriteException(Exception exception)
{
string errMsg = string.Format("{0}\r\n{1}", new object[]
{
exception.Message,
exception.StackTrace
});
LogHelper.WriteTextLog("Error", errMsg);
bool flag = exception.InnerException != null;
if (flag)
{
WriteException(exception.InnerException);
}
}
}
}
三、使用示例
消息发布示例
MQMsgTemp temp = new MQMsgTemp();
temp.ID = Guid.NewGuid().ToString();
temp.TempName = "测试消息";
temp.TempType = "测试";
temp.CreateUser = "我";
string jsonContentmq = Newtonsoft.Json.JsonConvert.SerializeObject(temp);
var produce = new ProduceWarpper();
produce.Open();
LogHelper.WriteTextLog("ActiveMq消息发布", jsonContentmq);
produce.ProduceQueueMsg("Test", jsonContentmq);
produce.Close();
发布后
消息订阅示例
//监听消息队列
var consumeProduce = new ConsumeWarpper();
consumeProduce.Open();
consumeProduce.ConsumeQueueMsg("Test", (msg) =>
{
LogHelper.WriteTextLog("ActiveMq消息订阅", msg);
MQMsgTemp temp = Newtonsoft.Json.JsonConvert.DeserializeObject<MQMsgTemp>(msg);
});
消息订阅后
附:日志等相关代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ActiveMqDemo
{
/// <summary>
/// 消息发送模板
/// </summary>
public class MQMsgTemp
{
/// <summary>
/// 主键
/// </summary>
public string ID { get; set; }
/// <summary>
/// 名称
/// </summary>
public string TempName { get; set; }
/// <summary>
/// 类别
/// </summary>
public string TempType { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string CreateUser { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ActiveMqDemo
{
public class LogHelper
{
/// <summary>
/// 写入日志到文本文件
/// </summary>
/// <param name="action">动作</param>
/// <param name="strMessage">日志内容</param>
public static void WriteTextLog(string action, string strMessage)
{
var time = DateTime.Now;
string path = AppDomain.CurrentDomain.BaseDirectory + @"Logs\";
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);
}
string fileFullPath = path + time.ToString("yyyy-MM-dd") + ".txt";
StringBuilder str = new StringBuilder();
str.Append("Time: " + time.ToString() + "\r\n");
str.Append("Action: " + action + "\r\n");
str.Append("Message: " + strMessage + "\r\n");
str.Append("-----------------------------------------------------------\r\n\r\n");
System.IO.StreamWriter sw;
if (!System.IO.File.Exists(fileFullPath))
{
sw = System.IO.File.CreateText(fileFullPath);
}
else
{
sw = System.IO.File.AppendText(fileFullPath);
}
sw.WriteLine(str.ToString());
sw.Close();
}
}
}