WCF分布式開發(fā)之MSMQ消息隊(duì)列
一、MSMQ簡(jiǎn)介
MSMQ(微軟消息隊(duì)列)是Windows操作系統(tǒng)中消息應(yīng)用程序的基礎(chǔ),是用于創(chuàng)建分布式、松散連接的消息通訊應(yīng)用程序的開發(fā)工具。
MSMQ與XML Web Services和.Net Remoting一樣,是一種分布式開發(fā)技術(shù)。但是在使用XML Web Services或.Net Remoting組件時(shí),Client端需要和Server端實(shí)時(shí)交換信息,Server需要保持聯(lián)機(jī)。MSMQ則可以在Server離線的情況下工作,將Message臨時(shí)保存在Client端的消息隊(duì)列中,以后聯(lián)機(jī)時(shí)再發(fā)送到Server端處理。
1、MSMQ的實(shí)現(xiàn)原理
消息的發(fā)送者把自己想要發(fā)送的信息放入一個(gè)容器,然后把它保存到一個(gè)系統(tǒng)公用空間的消息隊(duì)列中,本地或異地的消息接收程序再從該隊(duì)列中取出發(fā)給它的消息進(jìn)行處理。
消息隊(duì)列是一個(gè)公用存儲(chǔ)空間,它可以存在于內(nèi)存中或物理文件中,因此,消息以兩種方式發(fā)送,即快遞方式和可恢復(fù)模式。MSMQ機(jī)制類似QQ消息傳遞機(jī)制。下圖演示了MSMQ的實(shí)現(xiàn)原理。
2、安裝
默認(rèn)情況下安裝操作系統(tǒng)是不安裝消息隊(duì)列的,你可以在控制面板中找到添加/刪除程序,然后選擇添加/刪除Windows組件一項(xiàng),然后選擇應(yīng)用程序服務(wù)器,雙擊它進(jìn)入詳細(xì)資料中選擇消息隊(duì)列一項(xiàng)進(jìn)行安裝。
如果服務(wù)沒有自動(dòng)啟動(dòng),需要啟動(dòng)服務(wù):
3、兩個(gè)概念
一個(gè)是消息Message:Message是通信雙方需要傳遞的消息,它可以是文本、圖片、視頻等。消息包含發(fā)送和接收者的標(biāo)識(shí),只有指定的用戶才能取得消息。
另一個(gè)是隊(duì)列Queue:用來保存消息的存儲(chǔ)空間,消息對(duì)列分為3類:
- 公共隊(duì)列:MachineName\QueueName
能被別的機(jī)器所訪問,如果你的多個(gè)項(xiàng)目中用到消息隊(duì)列,那么你可以把隊(duì)列定義為公共隊(duì)列 - 專用隊(duì)列:MachineName\Private$\QueueName
只針對(duì)于本機(jī)的程序才可以調(diào)用的隊(duì)列,有些情況下為了安全起見定義為私有隊(duì)列。 - 日志隊(duì)列:MachineName\QueueName\Journal$
4、MicroSoft.Message.Queue常用的方法:
- Create方法:創(chuàng)建使用指定路徑的新消息隊(duì)列。
- Delete方法:刪除現(xiàn)有的消息隊(duì)列。
- Existe方法:查看指定消息隊(duì)列是否存在。
- GetPublicQueues方法:在“消息隊(duì)列”網(wǎng)絡(luò)中定位消息隊(duì)列。
- Send方法:發(fā)送消息到指定的消息隊(duì)列。
- GetAllMessages()方法:得到隊(duì)列中的所有消息。
- Receive/BeginReceive方法:檢索指定消息隊(duì)列中最前面的消息,并將其從該隊(duì)列中移除
- Peek/BeginPeek方法:查看某個(gè)特定隊(duì)列中的消息隊(duì)列,但不從該隊(duì)列中移出消息。。
- Purge方法:清空指定隊(duì)列的消息。
二、服務(wù)端
首先,實(shí)現(xiàn)服務(wù)器端。創(chuàng)建一個(gè)控制臺(tái)項(xiàng)目,添加System.Messaging引用,因?yàn)橄㈥?duì)列的類全部封裝在System.Messaging.dll程序集里。
服務(wù)器端代碼需要注意的是,公共隊(duì)列只能在域環(huán)境中創(chuàng)建,如果個(gè)人電腦沒有加入域環(huán)境,則不能創(chuàng)建公共隊(duì)列。
if (!MessageQueue.Exists(@".\MYFIRSTMSMQ")) { using (MessageQueue mq = MessageQueue.Create(@".\MYFIRSTMSMQ"))//創(chuàng)建一個(gè)公共消息隊(duì)列 { mq.Label = "myFirstMSMQ"; Console.WriteLine("已經(jīng)創(chuàng)建了一個(gè)公共隊(duì)列{0}", mq.Label); Console.WriteLine("公共隊(duì)列{0}的路徑為{1}", mq.Label, mq.Path); mq.Send("MSMQ 消息", "今天又學(xué)到個(gè)有趣的知識(shí)"); } } foreach (MessageQueue mq in MessageQueue.GetPublicQueues())//獲取所有公共隊(duì)列,發(fā)送消息 { mq.Send("發(fā)送公共消息隊(duì)列" + DateTime.Now.ToLongTimeString(), "今天又學(xué)到個(gè)有趣的知識(shí)"); Console.WriteLine("公有消息已經(jīng)送到{0}", mq.Path); } if (!MessageQueue.Exists(@".\Private$\MYFIRSTMSMQ")) { using (MessageQueue mq = MessageQueue.Create(@".\Private$\MYFIRSTMSMQ"))//創(chuàng)建一個(gè)私有消息隊(duì)列 { mq.Label = "myFirstPrivateMSMQ"; Console.WriteLine("已經(jīng)創(chuàng)建了一個(gè)私有隊(duì)列{0}", mq.Label); Console.WriteLine("私有隊(duì)列{0}的路徑為{1}", mq.Label, mq.Path); mq.Send("MSMQ 私有隊(duì)列消息" + "今天又學(xué)到個(gè)有趣的知識(shí)"); } } if (MessageQueue.Exists(@".\Private$\MYFIRSTMSMQ")) { MessageQueue mq = new MessageQueue(@".\Private$\MYFIRSTMSMQ");//找到私有隊(duì)列,發(fā)送消息 mq.Send("發(fā)送私有消息隊(duì)列" + DateTime.Now.ToLongTimeString() + "今天又學(xué)到個(gè)有趣的知識(shí)"); Console.WriteLine("私有消息已經(jīng)送到{0}", mq.Path); }
三、客戶端
服務(wù)器端把消息發(fā)送到共享的消息隊(duì)列中,然后,客戶端從這個(gè)共享的消息隊(duì)列中取出消息進(jìn)行處理。
if (MessageQueue.Exists(@".\MYFIRSTMSMQ"))// 獲取公共消息隊(duì)列 { using (MessageQueue mq = new MessageQueue(@".\MYFIRSTMSMQ"))//創(chuàng)建消息隊(duì)列對(duì)象 { mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" });//設(shè)置消息隊(duì)列的格式化器,還有BinaryMessageFormatter,ActiveXMessageFormatter等 foreach (Message msg in mq.GetAllMessages()) { Console.WriteLine("接收到的消息是:{0}", msg.Body); } Message firstmsg = mq.Receive(); Console.WriteLine("收到的第一條消息為:{0}", firstmsg.Body); } } if (MessageQueue.Exists(@".\Private$\MYFIRSTMSMQ"))// 獲取私有消息隊(duì)列 { using (MessageQueue mq = new MessageQueue(@".\Private$\MYFIRSTMSMQ")) { //.... } }
到此這篇關(guān)于WCF分布式開發(fā)之MSMQ消息隊(duì)列的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
c# 用Dictionary實(shí)現(xiàn)日志數(shù)據(jù)批量插入
這篇文章主要介紹了c# 用Dictionary實(shí)現(xiàn)日志數(shù)據(jù)批量插入的步驟,幫助大家更好的理解和使用c#中的Dictionary類,感興趣的朋友可以了解下2021-02-02C# 編碼好習(xí)慣,獻(xiàn)給所有熱愛c#的同志
c#編寫者,需要培養(yǎng)的一些好習(xí)慣2009-02-02C#靜態(tài)構(gòu)造函數(shù)用法實(shí)例分析
這篇文章主要介紹了C#靜態(tài)構(gòu)造函數(shù)用法,以實(shí)例形式較為詳細(xì)的分析了C#靜態(tài)構(gòu)造函數(shù)的用途、實(shí)現(xiàn)方法及使用技巧,需要的朋友可以參考下2015-06-06積累Visual Studio 常用快捷鍵的動(dòng)畫演示
在代碼開發(fā)過程中,頻繁的使用鍵盤、鼠標(biāo)操作非常麻煩,影響程序的開發(fā)效率。如何操作能用鍵盤來操作,那就節(jié)省時(shí)間了。下面小編把我平時(shí)積累的有關(guān)visul studio 常用快捷鍵的動(dòng)畫演示分享給大家,僅供大家參考2015-10-10C#托管內(nèi)存與非托管內(nèi)存之間的轉(zhuǎn)換的實(shí)例講解
在本篇文章里小編給大家整理了關(guān)于C#托管內(nèi)存與非托管內(nèi)存之間的轉(zhuǎn)換的實(shí)例以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-08-08C#/VB.NET實(shí)現(xiàn)PPT或PPTX轉(zhuǎn)換為圖像功能
由于大多數(shù)便攜式設(shè)備支持瀏覽圖片而不支持瀏覽PowerPoint 文件,所以相比較而言,圖像對(duì)于用戶而言更加友好。本文將利用C#/VB.NET實(shí)現(xiàn)PPT或PPTX轉(zhuǎn)換為圖像功能,需要的可以參考一下2022-08-08