返回首页
当前位置: 主页 > 互联网技术 > 云计算 >

微软消息队列的基础使用方式详解

时间:2016-09-30 22:56来源:电脑教程学习网 www.etwiki.cn 编辑:admin

Message Queue(微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。

【正文】

一   使用前的准备工作

在使用消息队列之前,需要在计算机中安装消息队列服务,安装方法如下:
1.      打开“控制面板”;
2.      打开“程序和功能”;
3.      点击“启用或关闭Windows功能”;
4.      展开“Microsoft Message Queue(MSMQ)服务器”,选中“Microsoft Message Queue(MSMQ)服务器核心”,点击“确定”按钮即可。
在代码中使用MSMQ,需要在项目中引用System.Messaging程序集,并在程序中引入System.Messaging命名空间。

二   消息队列的创建

2.1       消息队列的类型

消息队列分为用户自建队列和系统队列两大类,常用的用户自建队列有以下几种:
  公共队列:在整个消息网络复制,任何连接到队列所在计算机的站点均可访问;
  专用队列:仅在队列所在计算机上可用,只有知道队列的完整路径或者标签才能够访问。

系统队列有三种:
  日记队列:存储发送消息的副本和从队列中移除的消息副本;
  死信队列:存储无法传递或已过期的消息的副本;
  事务性死信队列:若无法传递或已过期的消息是事务性消息时,就存在事务性死信队列中。
消息队列还可以按照队列中存储的信息是否是事务性消息分为事务性队列和非事务性队列两种。对于事务性队列,在每次事务中发送的消息要么都发送成功要么都不成功。

2.2       消息队列实例的构造

消息队列的实例的默认构造函数为
MessageQueue queue=new MessageQueue();
queue.Path=” .\\Private$\\myQueue”;
在没有加域的计算机上只能构造专用队列,加入域的计算机上可以构造公共队列和专用队列。使用默认构造函数构造消息队列后必须设置Path属性才可以使用该队列,也可以使用其他构造函数在构造消息队列时就设置Path,例如
MessageQueue queue=new MessageQueue(“.\\Private$\\myQueue”);

Path参数的语法取决于要构造的消息队列的类型,如下所示:
  公共队列:MachineName\QueueName;
  专用队列:MachineName\Private$\QueueName;
  日记队列:MachineName\QueueName\Journal$;
  计算机日记队列:MachineName\Journal$;
  计算机死信队列:MachineName\Deadletter$;
  计算机事务性死信队列:MachineName\XactDeadletter$;

也可以使用格式名称或者标签来描述消息队列的路径:
  格式名称:FormatName: 格式名;
  标签:Label:标签。
格式名有如下几种:
  FormatName:Public= 5A5F7535-AE9A-41d4-935C-845C2AFF7112
  FormatName:DIRECT=SPX: NetworkNumber; HostNumber\QueueName
  FormatName:DIRECT=TCP: IPAddress\QueueName
  FormatName:DIRECT=OS: MachineName\QueueName
只有使用格式名才可以创建远程计算机上的消息队列实例,使用“MachineName\Private$\QueueName”的格式无法工作。

在本地计算机上创建消息队列的实例前,需要先判断指定Path的消息队列是否存在,若不存在,无法创建实例。判断的代码如下:
bool isExist= MessageQueue.Exist(“.\\Private$\\myQueue”);
若存在,返回值为true;若不存在,返回值为false。要注意的是,Exist方法不支持格式名称类型的Path,这也就意味着无法判断远程计算机上的指定队列是否存在。
当指定Path的消息队列不存在时,需要使用以下代码创建队列:
MessageQueue queue=MessageQueue.Create(“.\\Private$\\myQueue”);
该方法默认创建非事务性消息队列。如果要创建事务性消息队列,需要使用如下代码:
MessageQueue queue=MessageQueue.Create(“.\\Private$\\myQueue”,true);

关于消息列表的构造,总结如下:
  构造本地计算机上的消息队列:
MessageQueue queue = null;
if (MessageQueue.Exists(“.\\Private$\\myQueue”))
queue = new MessageQueue(“.\\Private$\\myQueue”);
else
           queue = MessageQueue.Create(“.\\Private$\\myQueue”, false);
  构造远程计算机上的消息队列:
MessageQueue queue = new MessageQueue(“FormatName:DIRECT=TCP: 127.0.0.1\QueueName.\\Private$\\myQueue”);

三   消息的发送

消息队列采用队列的形式存储所有的消息,因此先发送的消息比后发送的消息更靠近消息队列的头部。

3.1       非事务性消息的发送

发送非事务性消息的代码如下:
myQueue.Send(“消息数据”);
 

3.2       事务性消息的发送

发送事务性消息的代码如下:
MessageQueueTransaction myTransaction = new MessageQueueTransaction();
myTransaction.Begin();
myQueue.Send("消息数据", myTransaction);
myTransaction.Commit();
Send方法的参数类型为object,意味着可以发送任何类型的消息。

四   消息的接收

4.1       接收队列里的所有消息

如果要一次性接收队列里的所有消息,需要使用如下代码:
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
Message[] messages=queue.GetAllMessages();
foreach(Message msg in messages)
        {
            //做操作
        }
也可以使用:
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
MessageEnumerator enumerator = queue.GetMessageEnumerator2();
while(enumerator.MoveNext())
{
       Message message= enumerator.Current;
       //做操作
}
 

4.2       接收当前队列中的第一条消息

4.2.1      判断消息队列中是否有消息

在接收消息前,有以下两种方式判断队列中是否存在消息可以接收:
  获取所有消息,判断消息队列的长度是否大于0
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
if(queue. GetAllMessages().Length>0){//接收消息}
  获取消息游标,判断游标能否移动到第一条消息处:
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
MessageEnumerator enumerator = queue.GetMessageEnumerator2();
if(enumerator.MoveNext()){//接收消息}

4.2.2      接收第一条消息并移出队列

如果要接受第一条消息并且将该条消息从队列中删除,需要使用Receive()方法:
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
Message message=queue.Receive();

4.2.3      接收第一条消息不移出队列

如果要将消息保留在队列中,则应该用Peek()方法:
MessageQueue queue= new MessageQueue(“.\\Private$\\myQueue”);
Message message=queue.Peek();
 
无论是获取所有消息还是获取单条消息,获取到的都是Message的实例,而不是之前发送消息是传送的实例。要想将Message实例转换为所传送的实例,只需要对Message实例的Body属性做强制转换即可:
T t = (T)message.Body;
//做操作
 
以上就是微软消息队列的基本使用方式。
------分隔线----------------------------
标签(Tag):微软消息队列
------分隔线----------------------------
推荐内容
猜你感兴趣