最近vs2017神器正式版发布让人很是激动,vs2017支持了很多语言的开发,从前端-后端-底层的支持,堪称是工具中的神器;netcore我喜爱的架构之一也得到了大力的宣传,应群友的邀请将在队列工厂(msmq,redis,rabbitmq)一些列文章过后,继续增加.netcore方面的文章,只为.netcore发展更好贡献一份微弱的力量;本章内容分享的是队列(msmq,redis,rabbitmq)封装的队列工厂之MSMQ希望大家能够喜欢,也希望各位多多"扫码支持"和"推荐"谢谢!

» 创建队列工厂QueueReposity<T>

  . 队列公共操作接口IQueue

  . 配置文件操作类ConfClass<T>

  . 非安全单例创建队列实例

» Win7和Server2008安装MSMQ支持

» MSMQ测试用例(服务端+客户端)

下面一步一个脚印的来分享:

» 创建队列工厂QueueReposity<T>

首先,因为这里需要统一封装几个常用的队列方式的用法,因此采用了简单工厂模式,所以有了QueueReposity<T>

. 队列公共操作接口IQueue

工厂模式的特性创建实例,因为这里封装的都是队列,故而能提取出统一的规则来,因此定义了如下接口(这里没有考虑一些队列兼容的异步方法请忽略):

 /// <summary>
/// 队列公共操作
/// </summary>
public interface IQueue : IDisposable
{
/// <summary>
/// 创建队列
/// </summary>
void Create(); /// <summary>
/// 总数
/// </summary>
/// <returns></returns>
int Total(); /// <summary>
/// 读取一个队列
/// </summary>
/// <returns></returns>
Message Read(); ///// <summary>
///// 读取多个队列
///// </summary>
///// <returns></returns>
//List<Message> ReadAll(); /// <summary>
/// 写入队列
/// </summary>
/// <returns></returns>
bool Write(string content, string name = "");
}

. 配置文件操作类ConfClass<T>

因为每个队列的都有自己的配置信息,因此封装了统一管理的配置文件读取类ConfClass<T>,来读取配置在同一个xml文件中的配置信息,如下封装了自定义配置文件的属性和读取方法:

 #region 文件操作类
/// <summary>
/// 配置文件操作类
/// </summary>
/// <typeparam name="T"></typeparam>
public class ConfClass<T> where T : class,new()
{ public ConfClass() { var apiNodeName = this.GetType().Name;
Reader(apiNodeName);
} #region 单例模式 public static readonly object Singleton_Lock = new object(); /// <summary>
/// 单例对象
/// </summary>
private static T t = default(T); /// <summary>
/// 通过方法获取单例
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public static T GetInstance(T t)
{
t = t ?? new T();
return t;
} /// <summary>
/// 通过属性获取单例(在继承的时候使用)
/// </summary>
public static T Current
{
get
{
t = t ?? new T();
return t;
}
} #endregion #region 配置文件操作 #region 配置文件属性
/// <summary>
/// 配置文件地址
/// </summary>
//public string ConfPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Conf", "ShenNiuApi.xml");
public string ConfPath = @"C:\Conf\ShenNiuApi.xml"; /// <summary>
/// 配置文件父节点名称
/// </summary>
public string ConfParentNodeName = "ShenNiuApi"; /// <summary>
/// 配置文件内容
/// </summary>
public string ConfContent { get; set; } /// <summary>
/// 配置文件文档doc对象
/// </summary>
public XmlDocument doc { get; set; } /// <summary>
/// 账号
/// </summary>
public string UserName { get; set; } /// <summary>
/// 密码
/// </summary>
public string UserPwd { get; set; } /// <summary>
/// 接口地址
/// </summary>
public string ApiUrl { get; set; } /// <summary>
/// 秘钥
/// </summary>
public string ApiKey { get; set; } #endregion public ConfClass(string ConfPath, string ConfParentNodeName="")
{ this.ConfPath = string.IsNullOrWhiteSpace(ConfPath) ? this.ConfPath : ConfPath;
this.ConfParentNodeName = string.IsNullOrWhiteSpace(ConfParentNodeName) ? this.ConfParentNodeName : ConfParentNodeName; var apiNodeName = this.GetType().Name;
Reader(apiNodeName);
} /// <summary>
/// 读取配置信息
/// </summary>
/// <param name="apiNodeName"></param>
public void Reader(string apiNodeName)
{
try
{
if (string.IsNullOrWhiteSpace(ConfPath) || string.IsNullOrWhiteSpace(ConfParentNodeName))
{
throw new Exception("配置文件地址或者配置文件父节点名称不能为空");
} if (!File.Exists(ConfPath)) { return; } //获取配置文件信息
using (StreamReader reader = new StreamReader(ConfPath))
{
this.ConfContent = reader.ReadToEndAsync().Result;
} if (string.IsNullOrWhiteSpace(this.ConfContent)) { return; } //加入doc中
this.doc = new XmlDocument();
this.doc.LoadXml(this.ConfContent); //解析
var parentNode = string.Format("{0}/{1}", this.ConfParentNodeName, apiNodeName);
var apiNode = this.doc.SelectSingleNode(parentNode);
if (apiNode == null) { throw new Exception("未能找到" + parentNode + "节点"); } this.UserName = apiNode.SelectSingleNode("UserName").InnerText;
this.UserPwd = apiNode.SelectSingleNode("UserPwd").InnerText;
this.ApiUrl = apiNode.SelectSingleNode("ApiUrl").InnerText;
this.ApiKey = apiNode.SelectSingleNode("ApiKey").InnerText;
}
catch (Exception ex)
{ throw new Exception("加载配置文件" + this.ConfPath + "异常:" + ex.Message);
}
}
#endregion
}
#endregion

这个配置文件的类主要运用在队列实例继承上,只要继承了默认就会读取响应的配置节点信息;配置xml文件默认存储的地址: C:\Conf\ShenNiuApi.xml ,最大父节点名称默认:ShenNiuApi,格式如下所示:

 <ShenNiuApi>
<QMsmq>
<UserName></UserName>
<UserPwd></UserPwd>
<ApiUrl>.\Private$\MyMsmq</ApiUrl>
<ApiKey></ApiKey>
</QMsmq>
</ShenNiuApi>

. 非安全单例创建队列实例

由于工厂都是专门用来提供实例的存在,创建实例的模式也有很多这种,这里我选择的是非安全单例创建队列实例,所有在ConfClass类中默认加入了单例模式:

 #region 单例模式

             public static readonly object Singleton_Lock = new object();

             /// <summary>
/// 单例对象
/// </summary>
private static T t = default(T); /// <summary>
/// 通过方法获取单例
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public static T GetInstance(T t)
{
t = t ?? new T();
return t;
} /// <summary>
/// 通过属性获取单例(在继承的时候使用)
/// </summary>
public static T Current
{
get
{
t = t ?? new T();
return t;
}
} #endregion

因此这里所说的工厂模式通过泛型传递类型,再创建实例的具体代码只有这么点,简短精炼:

 /// <summary>
/// 队列工厂
/// </summary>
public class QueueReposity<T> where T : class,IQueue, new()
{
public static IQueue Current
{
get
{
return PublicClass.ConfClass<T>.Current;
}
}
}

» Win7和Server2008安装MSMQ支持

上面分享的是队列工厂的结构,到这里就要开始我们的第一个MSMQ队列的安装和封装分享了;首先来看Win7测试环境上怎么安装MSMQ的支持:开始菜单-》控制面板-》程序和功能:

-》打开或关闭Windows功能-》勾选如图所示队列安装组件:

-》确定等待安装完成;到此win7安装msmq就完成了,因为msmq是系统默认的所以安装起来很方便,当然server2008也差不多,按照如下操作安装(这里我使用租的阿里云Server2008R2服务器为例):开始-》控制面板-》程序(下面的打开或关闭Window功能)->功能-》添加功能-》消息队列:

在server上安装的步骤基本没啥变化,是不是很简单;安装完成后这样你的电脑或服务器就支持msmq了,此刻的你是不是很兴奋,觉得又能学到新东西了呵呵;

» MSMQ测试用例(服务端+客户端)

首先,这里我用控制台程序做测试用例,我分为客户端和服务端,用服务端通过分装的插入队列方法插入数据,然后通过客户端读取队列信息,先来上个图撑撑场面吧:

这里我创建了MSMQ的分装类 public class QMsmq : PublicClass.ConfClass<QMsmq>, IQueue 实现了队列接口IQueue和继承配置文件类ConfClass<QMsmq>,此时具体的方法体如下:

  public class QMsmq : PublicClass.ConfClass<QMsmq>, IQueue
{ private MessageQueue _msmq = null; public void Create()
{
if (string.IsNullOrWhiteSpace(this.ApiUrl)) { throw new Exception("创建队列需要指定队列:地址"); } _msmq = MessageQueue.Exists(this.ApiUrl) ?
new MessageQueue(this.ApiUrl) :
_msmq ?? MessageQueue.Create(this.ApiUrl);
//设置数据格式
_msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
} public int Total()
{
if (_msmq == null) { throw new Exception("请先创建队列"); }
return _msmq.GetAllMessages().Length;
} public Message Read()
{
try
{
if (_msmq == null) { throw new Exception("请先创建队列"); } //60s超时
return _msmq.Receive(TimeSpan.FromSeconds());
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
} //public List<Message> ReadAll()
//{
// try
// {
// if (_msmq == null) { throw new Exception("请先创建队列"); } // var messages = _msmq.GetAllMessages();
// return messages.ToList();
// }
// catch (Exception ex)
// {
// throw new Exception(ex.Message);
// }
//} public bool Write(string content, string name = "")
{
try
{
if (_msmq == null) { throw new Exception("请先创建队列"); }
if (string.IsNullOrWhiteSpace(content)) { throw new Exception("填充内容不能为空"); } var message = new Message();
message.Body = content;
message.Label = name;
_msmq.Send(message);
return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
} public void Dispose()
{
if (_msmq != null)
{
_msmq.Close();
_msmq.Dispose();
_msmq = null;
}
}
}

到这里我们的MSMQ简单封装代码已经完成了,咋们再来通过控制台调用下这个队列客户端代码

  class Program
{
static void Main(string[] args)
{
Client();
} /// <summary>
/// 客户端
/// </summary>
private static void Client()
{
//实例化QMsmq对象
var msmq = QueueReposity<QMsmq>.Current;
try
{
Console.WriteLine("创建:msmq");
msmq.Create(); while (true)
{
try
{
var result = msmq.Read();
Console.WriteLine(string.Format("接受第{0}个:{1}", result.Label, result.Body));
}
catch (Exception ex)
{ Console.WriteLine("异常信息:" + ex.Message); }
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
Console.WriteLine("释放。");
msmq.Dispose();
}
}
}

这里能够看出客户端代码中使用MSMQ步骤主要有:QueueReposity<QMsmq>.Current工厂创建自定义队列实例-》Create()创建-》Read()读取-》Dispose()释放mq,流程还算清晰吧;如下服务端代码:

  class Program
{
static void Main(string[] args)
{
Server();
} /// <summary>
/// 服务端
/// </summary>
private static void Server()
{
//实例化QMsmq对象
var msmq = QueueReposity<QMsmq>.Current; try
{
Console.WriteLine("创建:msmq");
msmq.Create(); var num = ;
do
{
Console.WriteLine("输入循环数量(数字,0表示结束):");
var readStr = Console.ReadLine();
num = string.IsNullOrWhiteSpace(readStr) ? : Convert.ToInt32(readStr); Console.WriteLine("插入数据:");
for (int i = ; i < num; i++)
{
var str = "我的编号是:" + i;
msmq.Write(str, i.ToString());
Console.WriteLine(str);
}
} while (num > );
}
catch (Exception ex)
{
}
finally
{
Console.WriteLine("释放。");
msmq.Dispose();
}
Console.ReadLine();
}
}

服务端的步骤几乎和客户端差不多,区别在于一个读取一个写入,服务端步骤:QueueReposity<QMsmq>.Current工厂创建自定义队列实例-》Create()创建-》Write()写入-》Dispose()释放mq;以上对MSMQ的代码分享和环境搭建讲解,希望能给您带来好的帮助,谢谢阅读;

队列工厂之(MSMQ)的更多相关文章

  1. 队列工厂之RabbitMQ

    本次和大家分享的是RabbitMQ队列的用法,前一篇文章队列工厂之(MSMQ)中在描述的时候已经搭建了简单工厂,因此本章内容是在其之上扩充的子项不再过多讲解工厂的代码了:RabbitMQ应该是现在互联 ...

  2. 队列工厂之RedisMQ

    本次和大家分享的是RedisMQ队列的用法,前两篇文章队列工厂之(MSMQ)和队列工厂之RabbitMQ分别简单介绍对应队列环境的搭建和常用方法的使用,加上本篇分享的RedisMQ那么就完成了咋们队列 ...

  3. 消息队列数量统计(MSMQ,Performance Counter)

    微软消息队列服务MSMQ (Microsoft Message Queue),工作在在线或者离线场景,并提供异步编程功能.互联网和企业开发很多场景应用,例如电商的订单处理流程,这是因为客户端不需要等待 ...

  4. 消息队列工具类(MSMQ)

    所要做的是简化msmq的调用代码以及做到可替代性,实现后,调用消息队列代码变为如下所示: QueueService srv = QueueService.Instance(); //检查存储DTO1的 ...

  5. Open Source

    资源来源于http://www.cnblogs.com/Leo_wl/category/246424.html RabbitMQ 安装与使用 摘要: RabbitMQ 安装与使用 前言 吃多了拉就是队 ...

  6. RedisMQ

    RedisMQ 本次和大家分享的是RedisMQ队列的用法,前两篇文章队列工厂之(MSMQ)和队列工厂之RabbitMQ分别简单介绍对应队列环境的搭建和常用方法的使用,加上本篇分享的RedisMQ那么 ...

  7. MSMQ队列学习记录

    微软消息队列-MicroSoft Message Queue(MSMQ) 使用感受:简单. 一.windows安装MSMQ服务 控制面板->控制面板->所有控制面板项->程序和功能- ...

  8. MSMQ队列的简单使用

    微软消息队列-MicroSoft Message Queue(MSMQ) 使用感受:简单. 一.windows安装MSMQ服务 控制面板->控制面板->所有控制面板项->程序和功能- ...

  9. 微软消息队列-MicroSoft Message Queue(MSMQ)队列的C#使用

    目录 定义的接口 接口实现 建立队列工厂 写入队列 获取消息 什么是MSMQ Message Queuing(MSMQ) 是微软开发的消息中间件,可应用于程序内部或程序之间的异步通信.主要的机制是:消 ...

随机推荐

  1. Eclipse 打开文件所在文件夹

    右击文件 > Show In > System Explorer

  2. Raphael的set使用

    Raphael的set使用 $(function() { initRaphael(); }); function initRaphael(e) { var paper = Raphael(0, 0, ...

  3. Java Ant Could not find the main class: org.eclipse.ant.internal.launching.remote.InternalAntRunner. Program

    参考:http://blog.csdn.net/jiangtaoking/article/details/49151763 The solution is to go to Run as → Exte ...

  4. Flex组件的生命周期

    组件实例化生命周期描述了用组件类创建组件对象时所发生的一系列步骤,作为生命周期的一部分,flex自动调用组件的的方法,发出事件,并使组件可见. 下面例子用as创建一个btn控件,并将其加入容器中 va ...

  5. MVC 怎么把string字符串转译成html格式

    Views层下:

  6. HoloLens开发手记 - 构建2D应用 Building 2D apps

    HoloLens可以让我们在真实世界中看到全息图像内容.但是它本质上还是一台Windows 10设备,这意味着HoloLens可以以2D应用形式运行Windows Store里的大部分UWP应用. 目 ...

  7. java服务器获取客户端ip

    在写服务端代码时,有时需要对客户端ip做认证,比如限制只有某些ip能访问,或者1个ip1天只能访问几次.最近就碰到个需要限制ip的情况,从网上找了一些服务器获取客户端ip的方法,说的都不太完善,这里整 ...

  8. HDU5477(模拟)

    A Sweet Journey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  9. 你真的了解如何将 Nginx 配置为Web服务器吗

    阅读之前,建议先阅读初识 Nginx. 之后,我们来了解一下 Nginx 配置. 抽象来说,将 Nginx 配置为 Web 服务器就是定义处理哪些 URLS 和如何处理这些URLS 对应的请求.具体来 ...

  10. 自己开发轻量级ORM(三)

    上一篇中简单分享了下ORM的设计思路.现在开始讲如何用代码来实现上篇的设计模型. 我们建2个类库来分别抽象数据库表结构关系映射和SQL增删改查操作. 打开VS2010,新建2个类库.分别起名为Mode ...