目錄
一、在學習Messagequeue 類之前,首先介紹一下MSMQ的一些理論上的知識 MSMQ(MicroSoft Message Queue,微軟消息隊列)官方的解釋是:在多個不同的應用之間實現相互通信的一種異步傳輸模式,相互通信的應用可以分布於同一台機器上,也可以分布於相連的網絡空間中的任一位置。MSMQ通過發送和接受消息使得應用程序之間的通信變的更快和更可靠。 它的實現原理是:消息的發送者把自己想要發送的信息放入一個容器中(我們稱之為Message),然后把它保存至一個系統公用空間的消息隊列(Message Queue)中;本地或者是異地的消息接收程序再從該隊列中取出發給它的消息進行處理。 在消息傳遞機制中,有兩個比較重要的概念。一個是消息,一個是隊列。消息是由通信的雙方所需要傳遞的信息,說白了它可以是各式各樣的媒體,如文本、聲音、圖象,在我們編程的時候,它一般是一個類的對象或字符串等,消息最終的理解方式,為消息傳遞的雙方事先商定,這樣做的好處是,一是相當於對數據進行了簡單的加密,二則采用自己定義的格式可以節省通信的傳遞量。隊列是發送和接收消息的公用存儲空間,它可以存在於內存中或者是物理文件中。 采用MSMQ帶來的好處是:由於是異步通信,無論是發送方還是接收方都不用等待對方返回成功消息,就可以執行余下的代碼,因而大大地提高了事物處理的能力;當信息傳送過程中,信息發送機制具有一定功能的故障恢復能力;MSMQ的消息傳遞機制使得消息通信的雙方具有不同的物理平台成為可能。在微軟的.net平台上利用其提供的MSMQ功能,可以輕松創建或者刪除消息隊列、發送或者接收消息、甚至於對消息隊列進行管理。
二:隊列類型(Queue Type) 由您或網絡中的其他用戶創建的隊列和系統隊列。用戶創建的隊列可能是以下任何一種隊列: “公共隊列”在整個“消息隊列”網絡中復制,並且有可能由網絡連接的所有站點訪問。 “專用隊列”不在整個網絡中發布。相反,它們僅在所駐留的本地計算機上可用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。 “管理隊列”包含確認在給定“消息隊列”網絡中發送的消息回執的消息。指定希望 MessageQueue 組件使用的管理隊列(如果有的話)。 “響應隊列”包含目標應用程序接收到消息時返回給發送應用程序的響應消息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。 系統生成的隊列一般分為以下幾類: “日記隊列”可選地存儲發送消息的副本和從隊列中移除的消息副本。每個“消息隊列”客戶端上的單個日記隊列存儲從該計算機發送的消息副本。在服務器上為每個隊列創建了一個單獨的日記隊列。此日記跟蹤從該隊列中移除的消息。 “死信隊列”存儲無法傳遞或已過期的消息的副本。如果過期或無法傳遞的消息是事務性消息,則被存儲在一種特殊的死信隊列中,稱為“事務性死信隊列”。死信存儲在過期消息所在的計算機上。有關超時期限和過期消息的更多信息,請參見默認消息屬性。 “報告隊列”包含指示消息到達目標所經過的路由的消息,還可以包含測試消息。每台計算機上只能有一個報告隊列。 “專用系統隊列”是一系列存儲系統執行消息處理操作所需的管理和通知消息的專用隊列。 在應用程序中進行的大多數工作都涉及訪問公共隊列及其消息。但是,根據應用程序的日記記錄、確認和其他特殊處理需要,在日常操作中很可能要使用幾種不同的系統隊列。
如果你相使用消息隊列進行通信的話,你就必須在你的電腦上安裝消息隊列,通過組件安裝,具體安裝的方法在這里就不詳解了,類似於安裝IIS一樣
對消息隊列有了簡單的了解后,使用MSMQ進行軟件開發需要安裝MSMQ,安裝完后就該進入實際的開發階段。具體的安裝過程就是在控制面板里“添加/刪除程序”下“添加/刪除Windows組件”,完成添加就OK。安裝完成后就可以通過交互界添加新的消息隊列,詳細如下圖:
出了上面這種交互界面來創建MSMQ外,也可以通過編程來完成。
在使用.net開發msmq時,你必須引入命名空System.Messaging
MessageQueue 支持兩種消息類型,同步和異步,同步方法使用的是peek();receive();異步使用的是:
Beginpeek() and Beginreceive();兩者沒有什么本質區別,都是封裝好的方法,你只要直接創建Messagequeue的對象來調用這個方法就OK了, 我想至於什么同步和異步是什么意思,就沒有必有解釋了吧,
五:MSMQ-發送消息到遠程專用隊列
------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging;
namespace MyQueue
{
public class MyMessageQueue
{
private string Path;
/// <summary>
/// 1.通過Create方法創建使用指定路徑的新消息隊列
/// </summary>
/// <param name="queuePath"></param>
public void Createqueue(string queuePath)
{
try
{
if (!MessageQueue.Exists(queuePath))
{
MessageQueue.Create(queuePath);
}
else
{
Console.WriteLine(queuePath + "已經存在!");
//MessageQueue.Delete(queuePath);
//MessageQueue.Create(queuePath);
//Console.WriteLine(queuePath + "刪除重建");
}
Path = queuePath;
}
catch (MessageQueueException e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
/// 2.連接消息隊列並發送消息到隊列
/// 遠程模式:MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:machinename//private$//queue");
/// rmQ.Send("sent to regular queue - Atul");對於外網的MSMQ只能發不能收
/// </summary>
public void SendMessage()
{
try
{
//連接到本地隊列
MessageQueue myQueue = new MessageQueue(Path);
//MessageQueue myQueue = new MessageQueue("FormatName:Direct=TCP:192.168.12.79//Private$//myQueue1");
//MessageQueue rmQ = new MessageQueue("FormatName:Direct=TCP:121.0.0.1//private$//queue");--遠程格式
Message myMessage = new Message();
myMessage.Body = "消息內容34kuangbo去死";
myMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
//發生消息到隊列中
myQueue.Send(myMessage);
Console.WriteLine("消息發送成功!");
Console.ReadLine();
}
catch (ArgumentException e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
/// 3.連接消息隊列並從隊列中接收消息
/// </summary>
public void ReceiveMessage()
{
MessageQueue myQueue = new MessageQueue(Path);
myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
try
{
//從隊列中接收消息
Message myMessage = myQueue.Receive();// myQueue.Peek();--接收后不消息從隊列中移除
string context = myMessage.Body.ToString();
Console.WriteLine("消息內容:" + context);
Console.ReadLine();
}
catch (MessageQueueException e)
{
Console.WriteLine(e.Message);
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
/// 4.清空指定隊列的消息
/// </summary>
public void ClealMessage()
{
MessageQueue myQueue = new MessageQueue(Path);
myQueue.Purge();
Console.WriteLine("已清空對了{0}上的所有消息",Path);
}
/// <summary>
/// 5.連接隊列並獲取隊列的全部消息
/// </summary>
public void GetAllMessage()
{
MessageQueue myQueue = new MessageQueue(Path);
Message[] allMessage = myQueue.GetAllMessages();
XmlMessageFormatter formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
for (int i = 0; i < allMessage.Length; i++)
{
allMessage[i].Formatter = formatter;
Console.WriteLine("第{0}機密消息為:{1}", i+1, allMessage[i].Body.ToString());
}
Console.ReadLine();
}
}
}