WCF 中的佇列
本節說明如何在 Windows Communication Foundation (WCF) 中使用佇列通訊。
當做 WCF 傳輸繫結排入佇列
在 WCF 中,合約會指定要交換的項目。 合約是一種與企業相關或應用程式特定的訊息交換。 繫結中會指定用來交換訊息 (或「如何交換」) 的機制。 WCF 中的繫結會封裝訊息交換的詳細資料。 這些繫結會公開組態旋鈕,讓使用者控制繫結所表示之傳輸或通訊協定的各個層面。 WCF 中的佇列會視為其他傳輸繫結處理,這對於許多佇列應用程式來說十分有利。 目前許多佇列應用程式都是透過其他遠端程序呼叫 (RPC) 型的分散式應用程式來撰寫,導致在遵循上和維護上都有難度。 有了 WCF,撰寫分散式應用程式的樣式就會一致許多,遵循和維護時也更為容易。 另外,藉由根據商務邏輯獨立析出交換機制,您可以更輕鬆地設定傳輸或進行變更,而不會影響應用程式特定的程式碼。 下圖會說明使用 MSMQ 做為傳輸之 WCF 服務和用戶端的結構。
如上圖所示,用戶端和服務只能定義應用程式語意 (Semantics),也就是合約和實作。 服務會使用偏好的設定來設定佇列繫結, 用戶端則會使用 ServiceModel 中繼資料公用程式工具 (Svcutil.exe) 來對服務產生一個 WCF 用戶端,並產生一個描述用來將訊息傳送至服務之繫結的組態檔。 因此,為了傳送佇列訊息,用戶端會具現化 WCF 用戶端並對其叫用作業。 使訊息傳送至傳輸佇列並傳輸至目標佇列。 如此一來,傳送和接收訊息的應用程式就可以避開佇列通訊的所有複雜操作。
有關 WCF 中佇列繫結的注意事項如下:
所有服務作業必須為單向,因為 WCF 中的預設佇列繫結不支援使用佇列的雙工通訊。 雙向通訊範例 (雙向通訊) 則會說明如何使用兩個單向合約,實作使用佇列的雙工通訊。
為了產生 WCF 用戶端,使用中繼資料交換就必須要在服務上有額外的 HTTP 端點,讓中繼資料可以直接經過查詢,以便產生 WCF 用戶端,並且取得繫結資訊以適當地設定佇列通訊。
按照這個佇列繫結,一定要有 WCF 外部的額外組態。 例如,使用 WCF 隨附的 NetMsmqBinding 類別時,您需要設定繫結,而且至少要設定訊息佇列 (MSMQ)。
下列章節會根據 MSMQ 說明 WCF 隨附的特定佇列繫結。
MSMQ
WCF 中的佇列傳輸會對其佇列通訊使用 MSMQ。
MSMQ 是 Windows 隨附的選用元件,而且會以 NT 服務的身分執行。 MSMQ 會擷取傳輸佇列中要進行傳輸的訊息,以及要傳遞至目標佇列的訊息。 MSMQ 佇列管理員會實作可靠訊息傳輸通訊協定,使訊息不會在傳輸期間遺失。 此通訊協定可以是原生通訊協定,或是 SOAP Reliable Message Protocol (SRMP) 這類 SOAP 架構的通訊協定。
在 MSMQ 中,佇列可以為異動式或非異動式。 交易式佇列可讓您在交易中擷取及傳送訊息,然後永久將訊息儲存在佇列中。 傳送至交易式佇列的訊息只會依序傳輸一次。 您可以使用非異動式佇列來同時傳送變動性 (volatile) 和永久性 (durable) 訊息。 傳送至非交易式佇列的訊息並不保證傳輸可靠,因此便有可能遺失訊息。
MSMQ 佇列的安全也可以使用向 Active Directory 目錄服務註冊的 Windows 身分識別來保護。 在安裝 MSMQ 時,您可以安裝 Active Directory 整合,而此時電腦必須是 Windows 網域網路的成員。
如需 MSMQ 的相關資訊,請參閱安裝訊息佇列 (MSMQ)。
NetMsmqBinding
<netMsmqBinding> 是 WCF 為兩個 WCF 端點所提供的佇列繫結,以便使用 MSMQ 來進行通訊。 因此,繫結會公開特定用於 MSMQ 的屬性。 不過,在 NetMsmqBinding
中不會公開所有 MSMQ 功能和屬性。 精簡型 NetMsmqBinding
是使用大多數客戶都認為足夠的最佳功能組來設計。
NetMsmqBinding
闡述了到目前為止以繫結屬性為形式討論的核心佇列概念。 這些屬性接著會向 MSMQ 傳達傳輸及傳送訊息的方式。 下列章節討論屬性分類。 如需詳細資訊,請參閱更完整描述特定屬性的概念主題。
ExactlyOnce 和 Durable 屬性
ExactlyOnce
和 Durable
屬性會影響在佇列之間傳輸訊息的方式:
ExactlyOnce
:設定為true
(預設值) 時,佇列通道會確定傳送的訊息沒有重複, 也會確定沒有遺失訊息。 如果無法傳送訊息,或者在可以傳送訊息之前訊息存留時間到期,就會在寄不出的信件佇列中記錄失敗的訊息和傳送失敗的原因。 設定為false
時,佇列通道會傳輸訊息。 在這個情況下,您可以選擇寄不出的信件佇列。Durable:
設定為true
(預設值) 時,佇列通道會確定 MSMQ 將訊息永久儲存在磁碟上。 因此,如果停止後重新啟動 MSMQ 服務,磁碟上的訊息就會傳輸至目標佇列或傳遞至服務。 設定為false
時,訊息會儲存在變動性存放區中,而且在停止後重新啟動 MSMQ 服務時會遺失。
如果是 ExactlyOnce
可靠傳輸,MSMQ 則會需要使用異動式佇列, 也需要從異動式佇列讀取異動。 因此,當您使用 NetMsmqBinding
時,異動一定會在 ExactlyOnce
設定為 true
的狀況下傳送或接收訊息。 同樣地,MSMQ 必須使用非交易式佇列才能得到最佳保證,例如當 ExactlyOnce
為 false
以及用於變動性傳訊時。 因此,將 ExactlyOnce
設定為 false
或將 durable 設定為 false
時,您無法使用異動來進行傳送或接收。
注意
您一定要根據繫結程序中的設定建立正確的佇列 (異動式或非異動式)。 如果 ExactlyOnce
為 true
,請使用交易式佇列,否則請使用非交易式佇列。
寄不出的信件佇列屬性
寄不出的信件佇列是用來儲存無法傳遞的訊息。 使用者可以撰寫補償邏輯,用來從寄不出的信件佇列中讀取訊息。
許多佇列系統都會提供全系統範圍之寄不出的信件佇列。 MSMQ 會對無法傳遞至非異動式佇列的訊息提供全系統範圍的非異動式寄不出的信件佇列,並對無法傳遞至異動式佇列的訊息提供全系統範圍的異動式寄不出的信件佇列。
如果將訊息傳送至不同目標佇列的用戶端共用 MSMQ 服務,則用戶端傳送的所有訊息都會移至同一個寄不出的信件佇列。 您不一定都要這麼做, 為了加強隔離效果,WCF 和 Windows Vista 中的 MSMQ 提供了自訂寄不出的信件佇列 (或是應用程式特定之寄不出的信件佇列),讓使用者可以指定這個佇列儲存無法傳遞的訊息。 因此,不同的用戶端就不會共用同一個寄不出的信件佇列。
繫結中有兩個重要的屬性:
DeadLetterQueue
:這個屬性是一種列舉,指出是否要求寄不出的信件佇列。 列舉中也包含寄不出的信件佇列種類 (如果有要求的話)。 這些值則為None
、System
和Custom
。 如需這些屬性解譯的詳細資訊,請參閱使用寄不出的信件佇列來處理訊息傳輸失敗CustomDeadLetterQueue
:這個屬性是應用程式特定之寄不出的信件佇列的統一資源識別碼 (URI) 位址。 此為必要項 (如果DeadLetterQueue
.Custom
已選擇的話)。
有害訊息處理屬性
當服務在異動中從目標佇列中讀取訊息時,可能會因為各種原因而無法處理訊息。 然後服務會將訊息放回佇列,以便再次讀取。 若要處理重複失敗的訊息,可以在繫結中設定一組有害訊息處理屬性。 有害訊息處理屬性有四個:ReceiveRetryCount
、MaxRetryCycles
、RetryCycleDelay
和 ReceiveErrorHandling
。 如需這些屬性的詳細資訊,請參閱有害訊息處理。
安全性屬性
MSMQ 會公開本身的安全性模型,例如佇列上或傳送驗證訊息上的存取控制清單 (ACL)。 NetMsmqBinding
會將這些安全性屬性當做部分傳輸安全性設定公開。 在傳輸安全性的繫結中有兩個屬性:MsmqAuthenticationMode
和 MsmqProtectionLevel
。 這些屬性中的設定取決於設定 MSMQ 的方式。 如需詳細資訊,請參閱使用傳輸安全性來保護訊息的安全。
除了傳輸安全性以外,也可以使用訊息安全性來保護實際的 SOAP 訊息本身。 如需詳細資訊,請參閱使用訊息安全性來保護訊息的安全。
MsmqTransportSecurity
也會公開 MsmqEncryptionAlgorithm
和 MsmqHashAlgorithm
這兩個屬性。 進行訊息的佇列對佇列傳輸加密,以及進行簽章雜湊處理時,可選用這些不同演算法的列舉。
其他屬性
除了上述屬性,下面也有繫結程序中公開的其他 MSMQ 特定屬性:
UseSourceJournal
:指出已開啟來源日誌記錄的屬性。 來源日誌記錄是一個 MSMQ 功能,可追蹤已順利從傳輸佇列傳輸的訊息。UseMsmqTracing
:指出已開啟 MSMQ 追蹤的屬性。 每次裝載 MSMQ 佇列管理員的電腦上有訊息傳入或傳出時,MSMQ 追蹤就會將報告訊息傳送至報告佇列。QueueTransferProtocol
:用於佇列對佇列訊息傳輸的通訊協定列舉。 MSMQ 會實作原生佇列對佇列傳輸通訊協定,以及稱為 SOAP Reliable Messaging Protocol (SRMP) 的 SOAP 架構通訊協定。 在佇列對佇列傳輸中使用 HTTP 傳輸時,就會使用 SRMP。 在佇列對佇列傳輸中使用 HTTPS 時,則會使用 SRMP。UseActiveDirectory
:布林值,指出是否必須使用 Active Directory 解析佇列位址。 根據預設,這個屬性為關閉狀態。 如需詳細資訊,請參閱服務端點與佇列定址。
MsmqIntegrationBinding
若要讓 WCF 端點與使用 C、C++、COM 或 System.Messaging API 所撰寫的現有 MSMQ 應用程式進行通訊,則會用到 MsmqIntegrationBinding
。
其繫結屬性與 NetMsmqBinding
一樣, 但是會有下列差異:
MsmqIntegrationBinding
的作業合約受限為採用類型為 MsmqMessage<T> 的單一參數,其中型別參數為本文類型。許多 MSMQ 原生訊息屬性會在 MsmqMessage<T> 中公開以供使用。
為了協助序列化和還原序列化訊息本文,XML 和 ActiveX 等序列化程式都會提供讓您使用。
範例程式碼
如需如何撰寫使用 MSMQ 之 WCF 服務的逐步指示,請參閱下列主題:
如需示範在 WCF 中使用 MSMQ 的完整程式碼範例,請參閱下列主題: