程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WCF分布式開發必備知識(1):MSMQ消息隊列

WCF分布式開發必備知識(1):MSMQ消息隊列

編輯:關於.NET

學習WCF是不是就不需要學習.Net Remoting、ASMX、WSE和MSMQ了?

這個問題一直是很多開發者關注的問題.按照微軟的說法,WCF是微軟分布式應用程序開發的集大成者,學習WCF編程,就不需要了解其他的技術.這個說法有一定的道理.WCF的出現確實解決了很多問題,它整合了.Net平台下所有的和分布式系統有關的技術,例如.Net Remoting、ASMX、WSE和MSMQ。以通信(Communiation)范圍而論,它可以跨進程、跨機器、跨子網、企業網乃至於 Internet;可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作為宿主(Host)。開發人員可以構建跨平台、安全、可靠和支持事務處理的企業級互聯應用解決方案。既然WCF如此強大,開發者再不用去分別了解.Net Remoting,ASMX等各種技術了。

可事實並非如此,首先,技術的更新換代沒有那麼迅速,我們接觸的工作平台和技術文章不會因為WCF的出現而全部更新,其次作為一個開發人員,在實際開發過程要學習或者解決技術問題,必須知道其相關的概念,扎實的基礎知識畢不可少.

在本節我們就來了解一下MSMQ的基本概念和開發過程.我們先來了解一下什麼是MSMQ:

MSMQ全稱MicroSoft Message Queue,微軟消息隊列,是在多個不同的應用之間實現相互通信的一種異步傳輸模式,相互通信的應用可以分布於同一台機器上,也可以分布於相連的網絡空間中的任一位置。它的實現原理是:消息的發送者把自己想要發送的信息放入一個容器中(我們稱之為Message),然後把它保存至一個系統公用空間的消息隊列(Message Queue)中;本地或者是異地的消息接收程序再從該隊列中取出發給它的消息進行處理.

其中兩個重要的概念。一個是消息Message ,一個是隊列Queue。

消息Message是由通信的雙方所需要傳遞的信息,它可以是各式各樣的媒體,如文本、聲音、圖象等等。消息最終的理解方式,為消息傳遞的雙方事先商定,這樣做的好處是,一是相當於對數據進行了簡單的加密,二則采用自己定義的格式可以節省通信的傳遞量。消息可以含有發送和接收者的標識,只有指定的用戶才能看到回執。時間戳,便於接收方對某些與時間相關的應用進行處理。截止時間,指定時間內消息還未到達則作廢。

隊列的類型主要包括一下幾種:

“公共隊列”在整個“消息隊列”網絡中復制,並且有可能由網絡連接的所有站點訪問。

“專用隊列”不在整個網絡中發布。相反,它們僅在所駐留的本地計算機上可用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。

“管理隊列”包含確認在給定“消息隊列”網絡中發送的消息回執的消息。指定希望 MessageQueue 組件使用的管理隊列(如果有的話)。

“響應隊列”包含目標應用程序接收到消息時返回給發送應用程序的響應消息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。

消息隊列Queue是發送和接收消息的公用存儲空間,它可以存在於內存中或者是物理文件中。消息可以以兩種方式發送,即快遞方式(express)和可恢復模式(recoverable),它們的區別在於,快遞方式為了消息放置於內存中,可恢復模式放於物理磁盤上(詳細參見MSDN).

了解到消息隊列MSMQ相關的基本概念以後,我們知道它的

優點:穩定、消息優先級、脫機能力以及安全性,有保障的消息傳遞和執行許多業務處理的可靠的防故障機制。

缺點:MSMQ不適合於Client需要Server端實時交互情況.大量請求時候,響應延遲.

優點決定了它的松耦合的特性,消息隊列同樣是實現SOA面向對象的架構的方式之一.現在我們就來看看簡單的MSMQ編程.

要在.net平台上進行MSMQ的開發,需要配置開發環境,安裝消息隊列,具體的安裝過程可以baidu,直接在安裝光盤裡查找安裝windows組件,選擇消息隊列安裝即可.

安裝結束後,可以在我的電腦--管理--消息隊列

這個證明你已經安裝成功.下面就可以來使用Visual Stdudio進行開發了.

首先,創建一個控制台項目(當然你也可以創建Web或者Winform應用程序).添加項目引用System.Messaging,因為消息隊列相關的類庫全部封裝在System.Messaging.dll程序集裡了.下面我們就來寫自己的代碼.

static void Main(string[] args)
        {
            //Create a public Queue
            if (!MessageQueue.Exists(@".\FrankMSMQ"))
            {
                using (MessageQueue mq = MessageQueue.Create(@".\FrankMSMQ"))
                {
                    mq.Label = "FrankPublicQueue";
                    Console.WriteLine("FrankPublicQueue is Created:");
                    Console.WriteLine("Path is {0}:", mq.Path);
                    Console.WriteLine("FrankPublicQueue' name is {0}:", mq.QueueName);
                    //Console.Read();
                    mq.Send("MSMQ Message", "Frank.Xu");
                }
            }//Create a private Queue
            if (!MessageQueue.Exists(@".\Private$\FrankMSMQ"))
            {
                using (MessageQueue mq = MessageQueue.Create(@".\Private$\FrankMSMQ"))
                {
                    mq.Label = "FrankPrivateQueue";
                    Console.WriteLine("FrankPrivateQueue is Created:");
                    Console.WriteLine("Path is {0}:", mq.Path);
                    Console.WriteLine("FrankPrivateQueue' name is {0}:", mq.QueueName);
                    //Console.Read();
                    mq.Send("MSMQ Private Message", "Frank.Xu");
                }
            }
            //Get all public queues and send new messages
            foreach (MessageQueue mq in MessageQueue.GetPublicQueues())
            {
                mq.Send("Sending MSMQ public message" + DateTime.Now.ToLongDateString(),"Frank.Xu");
                //string mName = mq.MachineName;
                Console.WriteLine("Public Message is sent to {0}:", mq.Path);
            }
            //find private queues and send new messages
            if (MessageQueue.Exists(@".\Private$\FrankMSMQ"))
            {
                MessageQueue mq = new MessageQueue(@".\Private$\FrankMSMQ");
                mq.Send("Sending MSMQ private message" + DateTime.Now.ToLongDateString(), "Frank.Xu");
                Console.WriteLine("Private Message is sent to {0}:", mq.Path);
            }
            Console.Read();
        }

比較重要的類就是MessageQueue,這行代碼創建消息隊列 MessageQueue mq = MessageQueue.Create(@".\FrankMSMQ"),參數是存放消息隊列的位置.這個基本就完成了創建和發送消息的主程序.下面我們來建立一個客戶端,來訪問消息隊列,獲取消息,同樣建立一個控制台應用程序,添加引用和代碼:

using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging;
namespace MSMQClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //Get public queue message
            if (MessageQueue.Exists(@".\FrankMSMQ"))//判斷是否存在消息隊列
            {
                using(MessageQueue mq = new MessageQueue(@".\FrankMSMQ"))//創建消息隊列對象
                {
                    mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" });//設置消息隊列的格式化器
                    //mq.Send("Sample Message", ":Label");
                    Message msg = mq.Receive();//從隊列接受消息
                    Console.WriteLine("Received MSMQ Message is :{0}", msg.Body);//輸出消息
                    //BinaryMessageFormatter
                    //ActiveXMessageFormatter
                }
                    //Console.Read();
            }
            //Get private queue message
            if (MessageQueue.Exists(@".\Private$\FrankMSMQ"))//判斷私有消息是否存在
            {
                using (MessageQueue mq = new MessageQueue(@".\Private$\FrankMSMQ"))
                {
                    mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" });//設置消息隊列格式化器
                    //mq.Send("Sample Message", ":Label");
                    Message msg = mq.Receive();//接收消息
                    Console.WriteLine("Received MSMQ Private Message is: {0}", msg.Body);//輸出消息
                }
            }
            Console.Read();
        }
    }
}

消息接收同樣需要實例化一個消息隊列對象, using(MessageQueue mq = new MessageQueue(@".\FrankMSMQ"))負責創建消息隊列對象.其次 mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" })這行代碼負責設置消息隊列的格式化器,因為消息的傳遞過程中存在格式化的問題.我們接收消息的時候必須指定消息隊列的格式化屬性Formatter,隊列才能接受消息.XmlMessageFormatter的作用是進行消息的XML串行化.BinaryMessageFormatter則把消息格式化為二進制數據進行傳輸.ActiveXMessageFormatter把消息同樣進行二進制格式化,區別是可以使用COM讀取隊列中的消息.

當然消息隊列還可以發送復雜的對象,前提是這個對象要可串行化,具體的格式取決與隊列的格式化器設置.此外消息隊列還支持事務隊列來確保消息只發送一次和發送的順序.

最近在研究SOA,所以系統系統學習一下WCF及其相關的技術,以上就是這個消息隊列的基本的概念和簡單的編程實現.下一節是關於.Net Remoting的基礎知識和開發的文章.~

我准備把WCF相關的幾個知識點都系統整理一下,包括代碼的實現.發出來一起與大家交流學習~

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved