本節說明如何在 Windows Communication Foundation (WCF) 中使用佇列通訊。
佇列作為 WCF 傳輸系結
在 WCF 中,合約會指定正在交換的內容。 合約是商務相關或應用程式特定的訊息交換。 用來交換訊息的機制(或「how」)是在系結中指定。 WCF 中的系結會封裝訊息交換的詳細數據。 他們會公開組態旋鈕,讓使用者控制傳輸或系結所代表之通訊協定的各個層面。 WCF 中的佇列會被視為任何其他傳輸系結,這對許多佇列應用程式來說都是一大優點。 如今,許多佇列應用程式會與其他遠端過程調用(RPC)樣式的分散式應用程式撰寫不同,因此難以遵循和維護。 使用 WCF 時,撰寫分散式應用程式的樣式大致相同,因此更容易遵循和維護。 此外,藉由將交換機制與商業規則分開分解,即可更輕鬆地設定傳輸或進行變更,而不會影響應用程式特定程序代碼。 下圖說明使用 MSMQ 做為傳輸的 WCF 服務和客戶端結構。
如上圖所示,用戶端和服務必須只定義應用程式語意,也就是合約和實作。 服務會設定具有慣用設定的佇列系結。 用戶端會使用 ServiceModel 元數據公用程式工具 (Svcutil.exe) 來產生服務的 WCF 用戶端,併產生組態檔,描述用來將訊息傳送至服務的系結。 因此,若要傳送已排入佇列的訊息,用戶端會具現化 WCF 用戶端,並在其上叫用作業。 這會導致訊息傳送至傳輸佇列,並傳送至目標佇列。 佇列通訊的所有複雜性都會被隱藏,使得應用程式在傳送和接收訊息時不需要面對這些複雜性。
WCF 中「佇列系結」的注意事項包括:
所有服務作業都必須是單向的,因為 WCF 中的預設佇列系結不支援使用佇列進行雙工通訊。 雙向通訊範例(Two-Way 通訊)說明如何使用兩項單向合約,透過佇列實現雙工通訊。
若要使用元數據交換產生 WCF 用戶端,服務上需要額外的 HTTP 端點,以便直接查詢它以產生 WCF 用戶端,並取得系結資訊以適當地設定佇列通訊。
根據佇列綁定,需要進行 WCF 以外的額外配置設定。 例如, NetMsmqBinding 隨附於 WCF 的類別需要您設定系結,以及最低限度地設定消息佇列 (MSMQ)。
下列各節說明 WCF 隨附的特定佇列系結,這些系結是以 MSMQ 為基礎。
MSMQ
WCF 中的佇列傳輸會使用 MSMQ 進行佇列通訊。
MSMQ 隨附為 Windows 的選用元件,並以 NT 服務的形式執行。 它會在傳輸佇列中擷取需要傳送的訊息,並在目標佇列中接收傳遞的訊息。 MSMQ 佇列管理員會實作可靠的訊息傳輸通訊協定,讓訊息不會在傳輸中遺失。 通訊協定可以是原生或SOAP型,例如SOAP Reliable Message Protocol(SRMP)。
在 MSMQ 中,佇列可以是交易式或非交易式。 交易式佇列允許在交易中擷取和傳遞訊息,然後永久儲存在佇列中。 傳送至交易式佇列的訊息會依序傳送一次。 您可以使用非交易式佇列來傳送非永久性及持久性訊息。 傳送至非交易式佇列的訊息不會包含任何可靠的傳輸保證:因此,訊息可能會遺失。
MSMQ 佇列也可以使用向 Active Directory 目錄服務註冊的 Windows 身分識別來保護。 安裝 MSMQ 時,您可以安裝 Active Directory 整合,這需要電腦成為 Windows 網域網路的一部分。
如需 MSMQ 的詳細資訊,請參閱 安裝消息佇列 (MSMQ)。
NetMsmqBinding
<netMsmqBinding> 是佇列系結 WCF 提供兩個 WCF 端點,以使用 MSMQ 進行通訊。 因此,系結會公開 MSMQ 特有的屬性。 不過,並非所有 MSMQ 的功能和屬性都在 NetMsmqBinding 中公開。 精簡版 NetMsmqBinding 是依據一組最優化的功能配置設計,大多數客戶應該認為這些功能足夠。
到目前為止所討論的核心佇列概念,以系結上的屬性形式展現出來。 這些屬性接著會與 MSMQ 溝通如何傳輸和傳遞訊息。 屬性類別的討論位於下列各節中。 如需詳細資訊,請參閱更完整描述特定屬性的概念主題。
ExactlyOnce 和 Durable 屬性
ExactlyOnce和 Durable 屬性會影響訊息在佇列之間傳輸的方式:
ExactlyOnce:當設定為true(預設值)時,佇列通道可確保訊息若已傳遞,就不會重複。 它也可確保訊息不會遺失。 如果無法傳遞訊息,或訊息 Time-To Live 在能夠傳遞前到期,則失敗的訊息以及傳遞失敗原因會記錄在死信佇列中。 當設定為false時,佇列通道會努力傳輸訊息。 在此情況下,您可以選擇選擇寄不出的信件佇列。Durable:當設定為true(預設值),佇列通道可確保 MSMQ 將訊息永久儲存在磁碟上。 因此,如果 MSMQ 服務要停止並重新啟動,磁碟上的訊息會傳送至目標佇列或傳遞至服務。 當設定為false時,訊息會儲存在揮發性存放區中,並在停止並重新啟動 MSMQ 服務時遺失。
若要進行 ExactlyOnce 可靠的傳輸,MSMQ 需要隊列為交易式。 此外,MSMQ 需要交易從交易佇列讀取。 因此,當您使用 NetMsmqBinding時,請記住:當 ExactlyOnce 設定為 true時,交易是必要的,以送出或接收訊息。 同樣地,MSMQ 要求佇列為非交易性,以取得最佳努力保證,例如當 ExactlyOnce 是 false 以及用於易失性訊息時。 因此,當將ExactlyOnce設為false或將耐久性設為false時,您無法使用交易來傳送或接收。
備註
確定已根據系結中的設定建立正確的佇列(交易式或非交易式)。 如果 ExactlyOnce 為 true,請使用交易式佇列,否則請使用非交易式佇列。
Dead-Letter 佇列屬性
死信佇列被用來儲存傳遞失敗的訊息。 用戶可以撰寫補償邏輯,以讀取寄不出的信件佇列中的訊息。
許多佇列系統都提供全系統的死信佇列。 MSMQ 提供系統範圍的非交易式死信佇列,供無法傳遞至非交易式佇列的訊息使用;同時也提供系統範圍的交易式死信佇列,供無法傳遞至交易式佇列的訊息使用。
如果多個用戶端傳送訊息至不同的目標佇列並共用 MSMQ 服務,那麼所有由這些用戶端傳送的訊息都會收集到相同的死信佇列中。 這不一定是比較好的。 為了獲得更好的隔離,Windows Vista 中的 WCF 和 MSMQ 會提供自定義寄不出的信件佇列(或應用程式特定的寄不出的信件佇列),供使用者指定以儲存傳遞失敗的訊息。 因此,不同的客戶端不會共用相同的死信佇列。
系結有兩個感興趣的屬性:
DeadLetterQueue:這個屬性是列舉類型,指出是否請求不送達信件佇列。 如果要求使用死信佇列,列舉中也會包含其類型。 這些值則為None、System和Custom。 如需這些屬性解譯的詳細資訊,請參閱 使用 Dead-Letter 佇列來處理訊息傳輸失敗CustomDeadLetterQueue:此屬性是應用程式特定死信佇列的統一資源識別碼位址。 如果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(MSMQ整合綁定)
當您想要讓 WCF 端點與以 C、C++、COM 或 System.Messaging API 撰寫的現有 MSMQ 應用程式進行通訊時,會使用MsmqIntegrationBinding。
系結屬性與的 NetMsmqBinding相同。 不過,適用下列差異:
作業合約
MsmqIntegrationBinding僅限於接受一個參數,其型別為主體型別MsmqMessage<T>。大部分 MSMQ 原生訊息屬性都會在MsmqMessage<T>中公開供使用。
為了協助處理訊息本文的串行化和還原串行化,會提供 XML 和 ActiveX 等串行化程式。
範例程式碼
如需如何撰寫使用 MSMQ 之 WCF 服務的逐步指示,請參閱下列主題:
如何:使用 WCF 端點交換佇列訊息
如需說明在 WCF 中使用 MSMQ 的完整程式代碼範例,請參閱下列主題: