最近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. js动态设置输入框字体/颜色

    动态设置文本框颜色: 主要是利用javascript中的触发事件onfocus和onblur <script language="javascript" type=" ...

  2. 如何从mysql中将数据导入到sqlserver

    本文讨论如何把MySQL的数据库导入到SQL Server中,所以首先你需要把两种数据库都安装了,再进行以下步骤. 一.为 MySQL安装ODBC驱动 1. 下载MySQL ODBC Connecto ...

  3. js连接sqlserver进行查询

    <script language="JavaScript"> // 创建数据库对象 var objdbConn = new ActiveXObject("AD ...

  4. Spring @Aspect实现切面编程

    参考:http://blog.csdn.net/cdl2008sky/article/details/6268628 参考:http://www.360doc.com/content/12/0602/ ...

  5. SVGEditor

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 百度人脸识别api及face++人脸识别api测试(python)

    一.百度人脸识别服务 1.官方网址:http://apistore.baidu.com/apiworks/servicedetail/464.html 2.提供的接口包括: 2.1 多人脸比对:请求多 ...

  7. POJ2407(欧拉函数)

    Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13598   Accepted: 6771 Descri ...

  8. webservice_模拟报文测试

    一.WebService测试小工具STORM  二.利用MyEclipse的WebService视图调用webservice Ø   除了客户端生成代码编写程序调用之外.还可以用MyEclipse提供 ...

  9. express框架介绍

    //引入express模块 var express = require('express'); //调用express方法,接受其返回值(返回值为对象) var app = express(); ap ...

  10. linux系统盘使用率达到100%的问题查找和解决方法

    今天公司云服务器报警系统发来短信,系统磁盘空间不够,登录服务器进行查看,磁盘使用虑达到100%,       感觉比较奇怪,所存的东西并不多,怎么会将磁盘占满,而且数据都是存在数据盘下,通过简单的进行 ...