MSMQ入门.doc_第1页
MSMQ入门.doc_第2页
MSMQ入门.doc_第3页
MSMQ入门.doc_第4页
MSMQ入门.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ASP.NET中进行消息处理(MSMQ)一MSMQ是微软消息队列的英文缩写。那么什么是消息队列?这些介绍网上一大片这里就不多说了。本文对于大虾级的人物来说这只是小玩意而已,对于初学者来说这文章还是有一定的帮助,希望路过的大虾们别笑话我班门弄斧。一、MSMQ介绍和安装消息队列使用消息队列的优点:稳定、消息优先级、脱机能力以及安全性。消息队列分为用户创建的队列(专用队列)和系统队列,用户队列分为,。我是Windows XP,看下图所示(myQueue为自己创建的消息队列,msmqtriggersnotifiations为通用队列):对消息队列有了简单的了解后,使用MSMQ进行软件开发需要安装MSMQ,安装完后就该进入实际的开发阶段。具体的安装过程就是在控制面板里“添加/删除程序”下“添加/删除Windows组件”,完成添加就OK。安装完成后就可以通过交互界添加新的消息队列,详细如下图:出了上面这种交互界面来创建MSMQ外,也可以通过编程来完成,.NET框架里的MessageQueue类下有一静态方法Create,用来完成消息队列的创建,其定义如下:1/2/摘要:3/在指定的路径中创建非事务性“消息队列”队列。4/5/参数:6/path:7/要创建的队列的路径。8/9/返回结果:10/表示新队列的System.Messaging.MessageQueue。11publicstaticMessageQueueCreate(stringpath);12/13/摘要:14/在指定的路径中创建事务性或非事务性“消息队列”队列。15/16/参数:17/transactional:18/如果创建事务性队列,为true;如果创建非事务性队列,则为false。19/20/path:21/要创建的队列的路径。22/23/返回结果:24/表示新队列的System.Messaging.MessageQueue。25publicstaticMessageQueueCreate(stringpath,booltransactional);实现消息队列的创建简单代码(C#),创建一个名为myQueue的非事务性消息队列,如下:MessageQueue.Create(.private$myQueue);二、创建、删除和管理队列在.NET环境下编写Message Queue程序的前提就是需要先安装MSMQ,本文之前已经作了详细的介绍。要开发MSMQ程序就必须学习一个很重要的类(MessageQueue),该类位于名称空间System.Messageing下。其中有几个常用的方法必须掌握:-Create方法:创建使用指定路径的新消息队列。-Delete方法:删除现有的消息队列。-Existe方法:查看指定消息队列是否存在。-GetAllMessages()方法:得到队列中的所有消息。-GetPublicQueues方法:在“消息队列”网络中定位消息队列。-Peek/BeginPeek方法:查看某个特定队列中的消息队列,但不从该队列中移出消息。-Receive/BeginReceive方法:检索指定消息队列中最前面的消息并将其从该队列中移除。-Send方法:发送消息到指定的消息队列。-Purge方法:清空指定队列的消息。上述列举的方法在此就不作详细介绍,大家可以通过下面的示例程序中来体会他们各自的功能。三、发送和序列化消息MSMQ消息队列中定义的消息由一个主体(body)和若干属性构成。消息的主体可以由文本、二进制构成,根据需要还可以被加密。在MSMQ 中消息的大小不能够超过4MB。发送消息是通过Send方法来完成的,需要一个Message参数。1、发送消息:步骤:连接队列-指定消息格式-提供要发送的数据(主体)-调用Send()方法将消息发送出去。详细见后面的示例程序。2、序列化消息:消息序列化可以通过.NET Framework附带的三个预定义格式化程序来完成:- XMLMessageFormatter对象-MessageQueue组件的默认格式化程序设置。- BinaryMessageFormatter对象;- ActiveXMessageFormatter对象;由于后两者格式化后的消息通常不能为人阅读,所以我们经常用到的是XMLMessageFormatter对象。该对象构造方法有三种重载: 1publicXmlMessageFormatter();2publicXmlMessageFormatter(stringtargetTypeNames);3publicXmlMessageFormatter(TypetargetTypes);如我们后面的示例程序中用到的序列化语句:1/序列化为字符串2XmlMessageFormatterformatter=newXmlMessageFormatter(newTypetypeof(string);四、读取和接收消息1、读取消息:也就是从指定队列中获取消息,详细请查看本文前面的关于消息操作的方法介绍。2、接收消息有两种方式:- 通过Receive方法-具体功能请返回本文前面有详细介绍。- 通过Peek方法-具体功能请返回本文前面有详细介绍。五、消息使用实例通过上面一系列的介绍,了解了MessageQueue类和常用的方法后,下面我们通过一个简单的示例程序来分析消息队列的创建、发送消息以及接收消息等相关知识点:1、通过Create方法创建使用指定路径的新消息队列1/*/2/通过Create方法创建使用指定路径的新消息队列3/4/5publicstaticvoidCreatequeue(stringqueuePath)67try89if(!MessageQueue.Exists(queuePath)1011MessageQueue.Create(.private$myQueue);1213else1415Console.WriteLine(queuePath+已经存在!);161718catch(MessageQueueExceptione)1920Console.WriteLine(e.Message);21222、连接消息队列并发送消息到队列1/*/2/连接消息队列并发送消息到队列3/4publicstaticvoidSendMessage()56try78/连接到本地的队列9MessageQueuemyQueue=newMessageQueue(.private$myQueue);1011MessagemyMessage=newMessage();12myMessage.Body=消息内容;13myMessage.Formatter=newXmlMessageFormatter(newTypetypeof(string);14/发送消息到队列中15myQueue.Send(myMessage);1617catch(ArgumentExceptione)1819Console.WriteLine(e.Message);20213、连接消息队列并从消息队列中接收消息1/*/2/连接消息队列并从队列中接收消息3/4publicstaticvoidReceiveMessage()56/连接到本地队列7MessageQueuemyQueue=newMessageQueue(.private$myQueue);8myQueue.Formatter=newXmlMessageFormatter(newTypetypeof(string);9try1011/从队列中接收消息12MessagemyMessage=myQueue.Receive();13stringcontext=(string)myMessage.Body;/获取消息的内容14Console.WriteLine(消息内容为:+context);1516catch(MessageQueueExceptione)1718Console.WriteLine(e.Message);1920catch(InvalidCastExceptione)2122Console.WriteLine(e.Message);23244、连接队列并清空队列的全部消息1/*/2/清空指定队列的消息3/4publicstaticvoidClearMessage()56MessageQueuemyQueue=newMessageQueue(.private$myQueue);7myQueue.Purge();85、连接队列并获取队列的全部消息1/*/2/连接队列并获取队列的全部消息3/4publicstaticvoidGetAllMessage()56/连接到本地队列7MessageQueuemyQueue=newMessageQueue(.private$myQueue);8Messagemessage=myQueue.GetAllMessages();9XmlMessageFormatterformatter=newXmlMessageFormatter(newTypetypeof(string);10for(inti=0;imessage.Length;i+)1112messagei.Formatter=formatter;13Console.WriteLine(messagei.Body.ToString();1415上面依次的列举出来5个方法,这里我就不做测试了。上述方法全部通过测试的。六、复杂消息发送实例通过上面一系列的介绍,对于简单消息的发送和接收及消息的管理应该都不会有什么问题了,下面我在介绍一下关于复杂的消息处理,现在有这样一个需求,要求通过消息队列将一本图书信息发送到队列里,然后从消息队列里读取出来。图书的基本信息包括图书编号、图书名称、图书作者以及图书定价,这样的一个复杂的对象类型怎么来传输呢?详细如下:1namespaceMSMQ.App23publicclassMsgQueue45/*/6/通过Create方法创建使用指定路径的新消息队列7/8/9publicstaticvoidCreatequeue(stringqueuePath)1011try1213if(!MessageQueue.Exists(queuePath)1415MessageQueue.Create(.private$myQueue);16MessageBox.Show(创建队列成功!);1718else1920MessageBox.Show(queuePath+已经存在!);212223catch(MessageQueueExceptione)2425MessageBox.Show(e.Message);26272829/*/30/连接消息队列并发送消息到队列31/32publicstaticboolSendMessage(Bookbook)3334boolflag=false;35try3637/连接到本地的队列38MessageQueuemyQueue=newMessageQueue(.private$myQueue);3940System.Messaging.MessagemyMessage=newSystem.Messaging.Message();41myMessage.Body=book;42myMessage.Formatter=newXmlMessageFormatter(newTypetypeof(MSMQ.App.Book);43/发送消息到队列中44myQueue.Send(myMessage);45flag=true;4647catch(ArgumentExceptione)4849MessageBox.Show(e.Message);5051returnflag;525354/*/55/连接消息队列并从队列中接收消息56/57publicstaticstringReceiveMessage()5859/连接到本地队列60MessageQueuemyQueue=newMessageQueue(.private$myQueue);61myQueue.Formatter=newXmlMessageFormatter(newTypetypeof(MSMQ.App.Book);62try6364/从队列中接收消息65System.Messaging.MessagemyMessage=myQueue.Receive();66Bookbook=(Book)myMessage.Body;/获取消息的内容67returnstring.Format(编号:0,书名:1,作者:2,定价:3,68book.BookId,69book.BookName,70book.BookAuthor,71book.BookPrice);7273catch(MessageQueueExceptione)7475MessageBox.Show(e.Message);7677catch(InvalidCastExceptione)7879MessageBox.Show(e.Message);8081returnnull;828384其实发送复杂的消息也就是在消息序列化上有些差别,别的地方与发送普通文本消息没什么大的变化,上面类里提供了创建队列,发送消息到队列,从队列获取消息三个方法,测试结果如下:上示例中,完成了一个复杂类型的消息发送到队列及从队列中读取的演义,详细请下载代码查看:ASP.NET中进行消息处理(MSMQ)二本文继续介绍MSMQ的相关知识点,通过一个示例程序来分析MSMQ在实际项目开发中的应用。建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:ASP.NET中进行消息处理(MSMQ)一。一、消息传递的优先级在MSMQ中消息在队列里传输是分有优先级的,这里我就以实例的形式介绍下关于优先级的使用,优先级一共有七种,MessagePriority枚举里全部进行了封装。因这里只作程序演示就不一一列举出,仅用了Highest和Normal两种类型,关于消息队列上进行消息传输的七种优先级大家可以参考我下面提供的MessagePriority枚举源代码定义。那么在发送消息的时候怎么指定消息的优先级呢?在Message对象里封装有一个属性Priority,接受一个枚举MessagePriority类型的值来设置消息传输的优先级。如下:1System.Messaging.Messagemessage=newSystem.Messaging.Message();2message.Priority=MessagePriority.Highest;/最高消息优先级下面来看看一个在消息传输中使用优先级的示例程序,通过示例程序会学习得更明白。示例程序界面:根据界面可知,提供了消息名字,消息优先级和消息内容三个输入项,前面曾经说过,这里为了方便演示就仅用了Highest和Normal两种类型,当点击发送消息的时候就通过是否选择优先级来设置消息的优先级,代码如下:1privatevoidbtnSend_Click(objectsender,EventArgse)23/连接到本地的专用队列myQueue4MessageQueuemyQueue=newMessageQueue(.private$myQueue);5System.Messaging.Messagemessage=newSystem.Messaging.Message();6message.Label=tbName.Text;7message.Body=tbContext.Text;89if(cbPriority.Checked)1011message.Priority=MessagePriority.Highest;1213else1415message.Priority=MessagePriority.Normal;1617myQueue.Send(message);18MessageBox.Show(成功发送消息到队列);19 这里我们可以向队列里发送两条消息,以便后面测试读取方法,发送两条消息到队列,此时,从队列消息中可以看到:刷新队列实质上就是把队列里的消息全部读取出来,具体的实现在ASP.NET中进行消息处理(MSMQ)一里已经作了详细的介绍,这里就不在多说,看看下面的代码: 1privatevoidDisplayMessage()23/连接到本地队列4MessageQueuemyQueue=newMessageQueue(.private$myQueue);5myQueue.MessageReadPropertyFilter.Priority=true;6DataTablemessageTable=newDataTable();7messageTable.Columns.Add(名字);8messageTable.Columns.Add(消息内容);9messageTable.Columns.Add(优先级);10XmlMessageFormatterformatter=newXmlMessageFormatter(newstringSystem.String);11try1213/从队列中接收消息14System.Messaging.Messagemessages=myQueue.GetAllMessages();15for(intindex=0;indexmessages.Length;index+)1617messagesindex.Formatter=formatter;1819stringlabel=messagesindex.Label;20stringbody=messagesindex.Body.ToString();21stringpriority=messagesindex.Priority.ToString();2223messageTable.Rows.Add(newstringlabel,body,priority);2425this.dgvMessage.DataSource=messageTable;2627catch(MessageQueueExceptione1)2829MessageBox.Show(e1.Message);303132 这里封装了一方法,专门负责从队列里读取全部消息并绑定在DataGridView控件上,这里我们只需要在按扭Click事件里调用这方法就OK。1privatevoidbtnRec_Click(objectsender,EventArgse)23DisplayMessage();4这就完成了给消息设置优先级的消息传输的应用,最终的测试结果如下:注:要完成以上应用还需注意一点,由于消息的优先级是枚举类型,在直接messagesindex.Priority.ToString();这种方式来获取优先级转化到字符串的时候,他需要一个过滤器(Filter),否则会抛出一个InvalidCastExceptionle类型的异常,异常信息接收消息时未检索到属性 Priority。请确保正确设置了 PropertyFilter。,要解决这问题只需要把消息对象的MessageReadPropertyFilter(过滤器) 的Priority设置为true就OK了。见上面代码里!.MessagePriority枚举源代码定义详细如下:1/摘要:2/指定消息队列在消息传递到队列的过程中应用于该消息的优先级,以及指定何时将消息插入目标队列。3publicenumMessagePriority45/摘要:6/最低消息优先级。7Lowest=0,8/9/摘要:10/位于Low和Lowest消息优先级之间。11VeryLow=1,12/13/摘要:14/低消息优先级。15Low=2,16/17/摘要:18/普通消息优先级。19Normal=3,20/21/摘要:22/位于System.Messaging.MessagePriority.High和System.Messaging.MessagePriority.Normal23/消息优先级之间。24AboveNormal=4,25/26/摘要:27/高消息优先级。28High=5,29/30/摘要:31/位于Highest和High消息优先级之间。32VeryHigh=6,33/34/摘要:35/最高消息优先级。36Highest=7,37二、事务性消息处理事务我想大家对这个词应该都不会陌生,在操作数据库的时候经常都会用到事务,确保操作成功,要么全部完成(成功),要么全部不完成(失败)。在MSMQ中利用事务性处理,可以确保事务中的消息按照顺序传送,只传送一次,并且从目的队列成功地被检索。那么,在MSMQ上使用事务性处理怎么实现呢?可以通过创建MessageQueueTransation类的实例并将其关联到MessageQueue组件的实例来执行,执行事务的Begin方法,并将其实例传递到收发方法。然后,调用Commit以将事务的更改保存到目的队列。创建事务性消息和普通的消息有一点小小的区别,大家可从下图上体会到:通过代码方式建立事务性消息队列只在Create方法的参数上动动手脚就OK,详细如下:1/创建普通的专用消息队列2MessageQueuemyMessage=MessageQueue.Create(.private$myQueue);3/创建事务性的专用消息队列4MessageQueuemyTranMessage=MessageQueue.Create(.private$myQueueTrans,true);启动了事务,那么在发送和接收消息的时候肯定是与原来有一定的差别的,这里我就不做详细介绍,下面给出示意性代码,有兴趣的朋友可以直接下载本文示例程序代码了解更多。普通的消息发送示意性代码:1/连接到本地的队列2MessageQueuemyQueue=newMessageQueue(.private$myQueue);3MessagemyMessage=newMessage();4myMessage.Body=消息内容;5myMessage.Formatter=newXmlMessageFormatter(newTypetypeof(string);6/发送消息到队列中7myQueue.Send(myMessage);启动了事务后的消息发送示意性代码1/连接到本地的队列2MessageQueuemyQueue=newMessageQueue(.private$myQueueTrans);34MessagemyMessage=newMessage();5myMessage.Body=消息内容;6myMessage.Formatter=newXmlMessageFormatter(newTypetypeof(string);78MessageQueueTransactionmyTransaction=newMessageQueueTransaction();9/启动事务10myTransaction.Begin();11/发送消息到队列中12myQueue.Send(myMessage,myTransaction);/加了事务13/提交事务14myTransaction.Commit();15Console.WriteLine(消息发送成功!); 读取消息示意性代码:1/连接到本地队列2MessageQueuemyQueue=newMessageQueue(.private$myQueueTrans);3myQueue.Formatter=newXmlMessageFormatter(newTypetypeof(string);4if(myQueue.Transactional)56MessageQueueTransactionmyTransaction=newMessageQueueTransaction();7/启动事务8myTransaction.Begin();9/从队列中接收消息10MessagemyMessage=myQueue.Receive(myTransaction);11stringcontext=myMessage.Bodyasstring;/获取消息的内容12myTransaction.Commit();13Console.WriteLine(消息内容为:+context);14三、异步消息处理在MSMQ中对消息的操作分有同步化操作和异步化操作两种,那两者到底有何区别呢?简单的说同步化操作就是一项操作没有完成前它将堵塞整个进程直到操作完成,下一项操作才会执行。所谓异步化操作则相反,不会堵塞启动操作的调用线程。如果你想在检索消息但不想堵塞其他程序的执行,则可使用异步消息处理。在MSMQ中异步接收消息使用BeginReceive方法和EndReceive方法来标记操作的开始和结束,异步查看消息则使用BeginPeek和EndPeek两个方法来标记异步读取的开始和结束。同时,异步接收和查看消息还可以指定超时时间,关于这点我在后续文章里再做详细的介绍,有兴趣的朋友可以关注。这里我将使用ASP.NET中进行消息处理(MSMQ)一一文里使用过的Book类来作为消息传输,没阅读过的朋友请先阅读这篇文章,了解Book类的结构。下面提供了一个示例,创建队列和发送消息到队列在前面我们已经使用多次了这里就不贴代码了,发送消息这里与第一篇文章中介绍如何发送一个复杂的类型信息到队列比,只是多了事务处理,详细如下:1/*/2/发送消息到队列3/4privatestaticvoidSendMessage()56MessageQueuemyQueue=newMessageQueue(.private$myAsyncQueue);7if(myQueue.Transactional)89Bookbook=newBook();10book.BookId=1001;11book.BookName=ASP.NET;12book.BookAuthor=ZhangSan;13book.BookPrice=88.88;14Messagemessage=newMessage(book);15message.Formatter=newXmlMessageFormatter(newTypetypeof(MSMQ.Async.Book);1617MessageQueueTransactionmyTransaction=newMessageQueueTransaction();18myTransaction.Begin();19myQueue.Send(message,myTransaction);20myTransaction.Commit();21Console.WriteLine(消息成功发送到队列!);2223异步接收消息:1/*/2/异步接收消息3/4privatestaticvoidAsyncReceiveMessage()56MessageQueuemyQueue=newMessageQueue(.private$myAsyncQueue);7if(myQueue.Transactional)89MessageQueueTransactionmyTransaction=newMessageQueueTransaction();10/这里使用了委托,当接收消息完成的时候就执行MyReceiveCompleted方法11myQueue.ReceiveCompleted+=newReceiveCompletedEventHandler(MyReceiveCompleted);12myQueue.Formatter=newXmlMessageFormatter(newTypetypeof(MSMQ.Async.Book);13myTransaction.Begin();14myQueue.BeginReceive();/启动一个没有超时时限的异步操作15signal.WaitOne();16myTransaction.Commit();17181privatestaticvoidMyReceiveCompleted(Objectsource,ReceiveCompletedEventArgsasyncResult)23try45MessageQueuemyQueue=(MessageQueue)source;6/完成指定的异步接收操作7Messagemessage=myQueue.EndReceive(asyncResult.AsyncResult);8signal.Set();9Bookbook=message.BodyasBook;10Console.WriteLine(图书编号:0-图书名称:1-图书作者:2-图书定价:3,11book.BookId.ToString(),12book.BookName,13book.BookAuthor,14book.BookPrice.ToString();15myQueue.BeginReceive();1617catch(MessageQueueExceptionme)1819Console.WriteLine(异步接收出错,原因:+me.Message);202122四、MSMQ在邮件发送程序中的应用在邮件程序的应用中,实现发送邮件的方法有很多种,很多朋友都比较喜欢邮件发送组件(如:JMail),在.NET Framework里也给我们提供了发送邮件的类StmpClient,位于System.Net下。我想很多朋友都曾用到过此类,如果说是在一个小型的邮件应用里,完全没有使用MSMQ的必要,因为数据量不大,直接处理就OK,这里我以邮件程序来说只是出于对MSMQ应用的介绍。说实在的,我也不知道怎么才能把这个东东给介绍清楚,先看看一张图吧!现在的需求是这样的,有一个邮件发送客户端(SendMail.aspx,界面效果如上图所示)和一个邮件发送管理的服务端(MailServer.aspx),当在SendMail.aspx里发送邮件的时候,我们不直接将其发到目标地址去,而是将其发送到消息队列,然后由MailServer.aspx来负责从消息队列里读取出邮件信息在将其发送到目标地址。其实SendMail.aspx的职责就是完成把邮件信息发送到消息队列,示意性代码如下:1protectedvoidbtnSendMail_Click(objectsender,EventArgse)23/取出数据存入MailInfo对象4MailInfoinfo=newMa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论