使用C#和MSMQ開發消息處理程序
2024-07-21 02:19:47
供稿:網友
簡介
msmq(微軟消息隊列)是windows操作系統中消息應用程序的基礎,是用于創建分布式、松散連接的消息通訊應用程序的開發工具。消息隊列和電子郵件有著很多相似處,他們都包含多個屬性,用于保存消息,消息類型中都指出發送者和接收者的地址;然而他們的用處卻有著很大的區別:消息隊列的發送者和接收者是應用程序,而電子郵件的發送者和接收者通常是人。
如同電子郵件一樣,消息隊列的發送和接收也不需要發送者和接收者同時在場,可以存儲在消息隊列或是郵件服務器中。因此,我們可以用下圖來描述msmq應用程序的體系結構:
從上圖可以看出,開發msmq應用程序并不是十分困難的事情。不過要使用msmq開發你的消息處理程序,必須在開發系統和使用程序的主機上安裝消息隊列。消息隊列的安裝屬于windows組件的安裝,和一般的組件安裝方法類似。安裝好消息隊列后,就可以開發你自己的消息處理程序了。不過有一點需要注意,如果你的計算機處于工作組中,而不是某個域中,可能你的公用隊列不能使用,不過這并不影響你的程序開發。
消息處理程序不外乎消息的發送和接收,然而要收發消息,還必須引用一個隊列,通常我們引用公用隊列和專用隊列,這兩個隊列都存放用戶生成的消息。引用隊列后,就可以發送、接收和閱讀消息了。消息接收服務位于system.messaging中,如果你找不到這一命名空間,你必須手動添加。點擊[項目]中的[添加引用],按下瀏覽按鈕,找到system.messaging.dll文件,添加進來即可。
引用隊列
引用隊列有三種方法,通過路徑、格式名和標簽引用隊列,這里我只介紹最簡單和最常用的方法:通過路徑應用隊列。隊列路徑的形式為 machinename/queuename。指向隊列的路徑總是唯一的。下表列出用于每種類型的隊列的路徑信息:
隊列類型
路徑中使用的語法
公共隊列
machinename/queuename
專用隊列
machinename/private$/queuename
日志隊列
machinename/queuename/journal$
如果是發送到本機上,還可以使用”.”代表本機名稱。具體的引用方法通過path屬性來進行,也可以在初始化消息隊列時進行。
如果在初始化時引用消息隊列,那么消息隊列必須存在于系統中,否則會產生中斷。往系統中添加隊列十分的簡單,打開[控制面板]中的[計算機管理],展開[服務和應用程序],找到并展開[消息隊列](如果找不到,說明你還沒有安裝消息隊列),右擊希望添加的消息隊列的類別,選擇新建隊列即可。當然,在程序中也可以實現消息隊列的創建,下文會有相應的說明。在初始化時引用消息隊列的代碼很簡單,如下所示:
messagequeue mq=new messagequeue(“.//private$//jiang”);
通過path屬性引用消息隊列的代碼也十分簡單:
messagequeue mq=new messagequeue();
mq.path=”.//private$//jiang”;
使用 create 方法可以在計算機上創建隊列:
system.messaging.messagequeue.create(@"./private$/jiang");
發送消息
隊列引用過后,就可以發送消息了。消息的發送可以分為簡單消息和復雜消息,簡單消息類型就是常用的數據類型,例如整型、字符串等數據;復雜消息的數據類型通常對應于系統中的復雜數據類型,例如結構,對象等等。
簡單消息的發送示例如下:
mq.send(1000); //發送整型數據
mq.send(“this is a test message!”); //發送字符串
復雜消息的發送和簡單消息的發送大同小異,只是發送時,通常不是直接給出發送的消息內容,而是代表發送消息內容的變量。下面的代碼分別通過消息變量和復雜數據類型變量發送一條復雜消息。
//下面的代碼中發送的消息由消息變量表示
message msg;
msg=new message(“a complex message!”);
msg.label=”this is the label”;
msg.priority=messagepriority.high;
mq.send(msg);
//下面的代碼中發送的消息由復雜數據類型變量表示,customer為自定義的一個類
customer customer = new customer();
customer.lastname = "copernicus";
customer.firstname = "nicolaus";
mq.send(customer);
接收消息
接收消息相比發送消息要復雜一點。接收消息由兩種方式:通過receive方法接收消息同時永久性地從隊列中刪除消息;通過peek方法從隊列中取出消息而不從隊列中移除該消息。如果知道消息的標識符(id),還可以通過receivebyid方法和peekbyid方法完成相應的操作。
接收消息的代碼很簡單:
mq.receive(); //或mq.receivebyid(id);
mq.peek(); // 或mq.peekbyid(id);
閱讀消息
接收到的消息只有能夠讀出來才是有用的消息,因此接收到消息以后還必須能讀出消息,而讀出消息算是最復雜的一部操作了。在應用程序能夠閱讀的消息和消息隊列中的消息格式不同,因而應用程序發送出去的消息經過序列化以后才發送給了消息隊列,這一過程由系統自動完成了,程序開發人員不必為此編寫代碼,然而在接收到消息后就面臨著消息序列化的問題。
消息的序列化可以通過visual studio 和 .net framework 附帶的三個預定義的格式化程序來完成:xmlmessageformatter 對象( messagequeue 組件的默認格式化程序設置)、binarymessageformatter 對象、activexmessageformatter 對象。由于后兩者格式化后的消息通常不能為人閱讀,所以我們經常用到的是xmlmessageformatter對象。
使用xmlmessageformatter對象格式化消息的代碼如下所示:
string[] types = { "system.string" };
((xmlmessageformatter)mq.formatter).targettypenames = types;
message m=mq.receive(new timespan(0,0,3));
將接收到的消息傳送給消息變量以后,通過消息變量m的body屬性就可以讀出消息了:
messagebox.show((string)m.body);
關閉消息隊列
消息隊列的關閉很簡單,和其他對象一樣,通過close函數就可以實現了:
mq.close();
到此為止,msmq應用程序的基礎知識就介紹完全了,但是開發出一個功能強大的msmq應用程序顯然不是這么簡單,要了解更詳細的資料可以參考msdn和windows操作系統中關于消息隊列的幫助內容。
中國最大的web開發資源網站及技術社區,