最近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

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1 /// <summary> 2     /// 队列公共操作 3     /// </summary> 4     public interface IQueue : IDisposable 5     { 6         /// <summary> 7         /// 创建队列 8         /// </summary> 9         void Create();10 11         /// <summary>12         /// 总数13         /// </summary>14         /// <returns></returns>15         int Total();16 17         /// <summary>18         /// 读取一个队列19         /// </summary>20         /// <returns></returns>21         Message Read();22 23         ///// <summary>24         ///// 读取多个队列25         ///// </summary>26         ///// <returns></returns>27         //List<Message> ReadAll();28 29         /// <summary>30         /// 写入队列31         /// </summary>32         /// <returns></returns>33         bool Write(string content, string name = "");34     }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  文件操作类                                                  ConfClass<T>  T : ,                                  apiNodeName =                  单例模式                  Singleton_Lock =                                                           T t =                                                                                                       t = t ??                                                                                                                   t = t ??                                                     配置文件操作                配置文件属性                                                                     ConfPath =                                                          ConfParentNodeName =                                                          ConfContent { ;                                                         XmlDocument doc { ;                                                           UserName { ;                                                          UserPwd { ;                                                          ApiUrl { ;                                                          ApiKey { ;                              ConfClass( ConfPath,  ConfParentNodeName=                   .ConfPath = .IsNullOrWhiteSpace(ConfPath) ?                  .ConfParentNodeName = .IsNullOrWhiteSpace(ConfParentNodeName) ?                    apiNodeName =                                                                          Reader(                                         (.IsNullOrWhiteSpace(ConfPath) ||                             Exception(                        (!File.Exists(ConfPath)) {                                             (StreamReader reader =                           .ConfContent =                        (.IsNullOrWhiteSpace(.ConfContent)) {                                            .doc =                      .doc.LoadXml(                                            parentNode = .Format(,                       apiNode =                       (apiNode == ) {   Exception( + parentNode +                       .UserName = apiNode.SelectSingleNode(                     .UserPwd = apiNode.SelectSingleNode(                     .ApiUrl = apiNode.SelectSingleNode(                     .ApiKey = apiNode.SelectSingleNode(                                           Exception( + .ConfPath +  +

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

1 <ShenNiuApi>2     <QMsmq>3         <UserName></UserName>4         <UserPwd></UserPwd>5         <ApiUrl>.\Private$\MyMsmq</ApiUrl>6         <ApiKey></ApiKey>7     </QMsmq>8 </ShenNiuApi>

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1 #region 单例模式 2  3             public static readonly object Singleton_Lock = new object(); 4  5             /// <summary> 6             /// 单例对象 7             /// </summary> 8             private static T t = default(T); 9 10             /// <summary>11             /// 通过方法获取单例12             /// </summary>13             /// <param name="t"></param>14             /// <returns></returns>15             public static T GetInstance(T t)16             {17                 t = t ?? new T();18                 return t;19             }20 21             /// <summary>22             /// 通过属性获取单例(在继承的时候使用)23             /// </summary>24             public static T Current25             {26                 get27                 {28                     t = t ?? new T();29                     return t;30                 }31             }32 33             #endregion

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1 /// <summary> 2     /// 队列工厂 3     /// </summary> 4     public class QueueReposity<T> where T : class,IQueue, new() 5     { 6         public static IQueue Current 7         { 8             get 9             {10                 return PublicClass.ConfClass<T>.Current;11             }12         }13     }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 

? Win7和Server2008安装MSMQ支持

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

 

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

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1  public class QMsmq : PublicClass.ConfClass<QMsmq>, IQueue 2     { 3  4  5         private MessageQueue _msmq = null; 6  7         public void Create() 8         { 9             if (string.IsNullOrWhiteSpace(this.ApiUrl)) { throw new Exception("创建队列需要指定队列:地址"); }10 11             _msmq = MessageQueue.Exists(this.ApiUrl) ?12                 new MessageQueue(this.ApiUrl) :13                 _msmq ?? MessageQueue.Create(this.ApiUrl);14             //设置数据格式15             _msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });16         }17 18         public int Total()19         {20             if (_msmq == null) { throw new Exception("请先创建队列"); }21             return _msmq.GetAllMessages().Length; 
22         }23 24         public Message Read()25         {26             try27             {28                 if (_msmq == null) { throw new Exception("请先创建队列"); }29 30                 //60s超时31                 return _msmq.Receive(TimeSpan.FromSeconds(60));32             }33             catch (Exception ex)34             {35                 throw new Exception(ex.Message);36             }37         }38 39         //public List<Message> ReadAll()40         //{41         //    try42         //    {43         //        if (_msmq == null) { throw new Exception("请先创建队列"); }44 45         //        var messages = _msmq.GetAllMessages();46         //        return messages.ToList();47         //    }48         //    catch (Exception ex)49         //    {50         //        throw new Exception(ex.Message);51         //    }52         //}53 54         public bool Write(string content, string name = "")55         {56             try57             {58                 if (_msmq == null) { throw new Exception("请先创建队列"); }59                 if (string.IsNullOrWhiteSpace(content)) { throw new Exception("填充内容不能为空"); }60 61                 var message = new Message();62                 message.Body = content;63                 message.Label = name;64                 _msmq.Send(message);65                 return true;66             }67             catch (Exception ex)68             {69                 throw new Exception(ex.Message);70             }71         }72 73         public void Dispose()74         {75             if (_msmq != null)76             {77                 _msmq.Close();78                 _msmq.Dispose();79                 _msmq = null;80             }81         }82     }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1  class Program 2     { 3         static void Main(string[] args) 4         { 5             Client(); 6         } 7  8         /// <summary> 9         /// 客户端10         /// </summary>11         private static void Client()12         {13             //实例化QMsmq对象14             var msmq = QueueReposity<QMsmq>.Current;15             try16             {17                 Console.WriteLine("创建:msmq");18                 msmq.Create();19 20                 while (true)21                 {22                     try23                     {24                         var result = msmq.Read();25                         Console.WriteLine(string.Format("接受第{0}个:{1}", result.Label, result.Body));26                     }27                     catch (Exception ex)28                     { Console.WriteLine("异常信息:" + ex.Message); }29                 }30             }31             catch (Exception ex)32             {33                 throw ex;34             }35             finally36             {37                 Console.WriteLine("释放。");38                 msmq.Dispose();39             }40         }41     }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1  class Program 2     { 3         static void Main(string[] args) 4         { 5             Server(); 6         } 7  8         /// <summary> 9         /// 服务端10         /// </summary>11         private static void Server()12         {13             //实例化QMsmq对象14             var msmq = QueueReposity<QMsmq>.Current;15 16             try17             {18                 Console.WriteLine("创建:msmq");19                 msmq.Create();20 21                 var num = 0;22                 do23                 {24                     Console.WriteLine("输入循环数量(数字,0表示结束):");25                     var readStr = Console.ReadLine();26                     num = string.IsNullOrWhiteSpace(readStr) ? 0 : Convert.ToInt32(readStr);27 28                     Console.WriteLine("插入数据:");29                     for (int i = 0; i < num; i++)30                     {31                         var str = "我的编号是:" + i;32                         msmq.Write(str, i.ToString());33                         Console.WriteLine(str);34                     }35                 } while (num > 0);36             }37             catch (Exception ex)38             {39             }40             finally41             {42                 Console.WriteLine("释放。");43                 msmq.Dispose();44             }45             Console.ReadLine();46         }47     }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

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


延伸阅读

告别“老顽固”-Java培训,做最负责任的教育,学习改变命运,软件学习,再就业,大学生如何就业,帮大学生找到好工作,lphotoshop培训,电脑培训,电脑维修培训,移动软件开发培训,网站设计培训,网站建设培训告别“老顽固”