本主題討論用戶端如何處理從佇列讀取的服務,以及服務端點如何對應至佇列。 提醒您,下圖顯示傳統 Windows Communication Foundation (WCF) 佇列應用程式部署。
若要讓用戶端將訊息傳送至服務,用戶端會將訊息指定給目標佇列。 若要讓服務從佇列讀取訊息,它會將其接聽位址設定為目標佇列。 WCF 中的尋址是以統一資源標識碼 (URI) 為基礎,而消息佇列 (MSMQ) 佇列名稱不是以 URI 為基礎的。 因此,請務必瞭解如何使用 WCF 處理 MSMQ 中建立的佇列。
MSMQ 尋址
MSMQ 會使用路徑和格式名稱來識別佇列。 路徑會指定主機名稱和 QueueName。 如果需要,主機名和 Private$ 之間可以有 QueueName,表示私人佇列未在 Active Directory 目錄服務中發佈。
路徑名會映射到「FormatNames」,以判斷地址的更多資訊,包括路由和佇列管理員傳輸協定。 佇列管理員支援兩種傳輸通訊協定:原生 MSMQ 通訊協定和 SOAP 可靠傳訊通訊協定(SRMP)。
如需 MSMQ 路徑和格式名稱的詳細資訊,請參閱 關於消息佇列。
NetMsmqBinding 和服務位址設定
將訊息尋址至服務時,會根據用於通訊的傳輸來選擇 URI 中的配置。 WCF 中的每個傳輸都有唯一的協議。 配置必須反映用於通訊的傳輸本質。 例如,net.tcp、net.pipe、HTTP 等等。
WCF 中的 MSMQ 佇列傳輸會公開 net.msmq 配置。 使用 net.msmq 格式的任何訊息,都是透過< c0 /> MSMQ 佇列傳輸通道發送。
WCF 中佇列的定址是以下列模式為基礎:
net.msmq: // <host-name> / [private/] <queue-name>
地點:
< 主機名稱>是裝載目標佇列的主機名稱。
[private] 是選擇性的。 當要處理一個私人佇列的目標佇列時,就會使用它。 若要處理公用佇列,您不得指定私用。 請注意,不同於 MSMQ 路徑,WCF URI 窗體中沒有 “$”。
< queue-name> 是佇列的名稱。 佇列名稱也可以參考子佇列。 因此,<queue-name> = <name-of-queue>[;sub-queue-name]。
範例1:若要解決裝載於計算機 abc atadatum.com 的私人佇列 PurchaseOrders,URI 會是 net.msmq://abc.adatum.com/private/PurchaseOrders。
範例 2:若要解決裝載於計算機 def atadatum.com 上的公用佇列 AccountsPayable,URI 會是 net.msmq://def.adatum.com/AccountsPayable。
接聽程式會使用佇列位址作為接聽 URI 來讀取訊息。 換句話說,佇列位址等同於 TCP 套接字的接聽埠。
從佇列讀取的端點必須使用先前開啟 ServiceHost 時所指定的相同配置來指定佇列的位址。 如需範例,請參閱 Net MSMQ 系結。
佇列中的多個合約
佇列中的訊息可以實作不同的合約。 在此情況下,成功讀取和處理所有訊息必須符合下列其中一項:
指定實作所有合約之服務的端點。 這是建議的方法。
指定具有不同合約的多個端點,但請確定所有端點都使用相同的
NetMsmqBinding物件。 ServiceModel 中的分派邏輯會使用訊息泵,從傳輸通道讀取訊息以進行分派,最終會根據合約將訊息分解至不同的端點。 系統會為接聽 URI/系結組建立訊息幫浦。 佇列位址會作為佇列接聽程式的接聽 URI 使用。 讓所有端點都使用相同的綁定物件,確保使用單一訊息幫浦來讀取訊息,並根據合約分配至相關端點。
SRMP 傳訊
如先前所述,您可以使用 SRMP 通訊協定進行佇列對佇列傳輸。 當 HTTP 傳輸在傳輸佇列與目標佇列之間傳輸訊息時,通常會使用此方式。
若要使用 SRMP 傳輸通訊協定,請使用 net.msmq 網路 URI 配置來尋址訊息,如先前所述,並在QueueTransferProtocol的NetMsmqBinding屬性中指定 SRMP 或安全 SRMP 的選擇。
指定 QueueTransferProtocol 屬性是僅限傳送的功能。 這是用戶端要使用的佇列傳輸通訊協定類型指示。
使用 Active Directory
MSMQ 提供支援以整合 Active Directory。 當 MSMQ 與 Active Directory 整合一起安裝時,機器必須是 Windows 網域的一部分。 Active Directory 用來發佈佇列以供探索;這類佇列稱為 公用佇列。 處理佇列時,可以使用 Active Directory 解析佇列。 這類似於網域名稱系統 (DNS) 用來解析網路名稱的IP位址的方法。 中的 UseActiveDirectoryNetMsmqBinding 屬性是布爾值,指出佇列通道是否必須使用 Active Directory 解析佇列 URI。 根據預設,它會設定為 false。
UseActiveDirectory如果 屬性設定為 true,則佇列通道會使用 Active Directory 將 net.msmq:// URI 轉換為格式名稱。
屬性 UseActiveDirectory 僅適用於傳送訊息的客戶端,因為它用來解析傳送訊息時的佇列位址。
將 net.msmq URI 對應至消息佇列格式名稱
佇列通道會處理將提供給通道的 net.msmq URI 名稱對應至 MSMQ 格式名稱。 下表總結了用來在它們之間進行映射的規則。
| WCF URI 型佇列位址 | 使用 Active Directory 屬性 | 佇列傳輸通訊協定屬性 | 產生的 MSMQ 格式名稱 |
|---|---|---|---|
Net.msmq://<machine-name>/private/abc |
False (預設值) | 原生 (預設值) | DIRECT=OS:machine-name\private$\abc |
Net.msmq://<machine-name>/private/abc |
否 | SRMP | DIRECT=http://machine/msmq/private$/abc |
Net.msmq://<machine-name>/private/abc |
對 | 本地人 |
PUBLIC=some-guid (佇列的 GUID) |
從 Dead-Letter 佇列或 Poison-Message 佇列讀取訊息
若要從作為目標佇列子佇列的有害訊息佇列讀取訊息,請使用子佇列的地址開啟 ServiceHost 。
範例:從本機計算機讀取 PurchaseOrders 私人佇列毒性訊息佇列的服務,會指定 net.msmq://localhost/private/PurchaseOrders;poison。
若要從系統事務性的死信佇列讀取訊息,URI 的格式必須是:net.msmq://localhost/system$;DeadXact。
若要從系統非交易型死信佇列讀取訊息,URI 的格式必須是:net.msmq://localhost/system$;DeadLetter。
使用自訂的死信佇列時,請注意死信佇列必須位於本機電腦上。 因此,死信佇列的 URI 限制為下列格式:
net.msmq: //localhost/ [private/] <custom-dead-letter-queue-name>。
WCF 服務會驗證它接收的所有訊息是否已正確發送至它正在接聽的特定佇列。 如果訊息的目的地佇列與找到的佇列不符,服務就不會處理訊息。 這是服務監聽死信佇列時必須處理的問題,因為死信佇列中的任何訊息本來應該送往其他地方。 若要從死信佇列或毒藥佇列讀取訊息, 必須使用具有 ServiceBehavior 參數的 Any 。 如需範例,請參閱 死信佇列。
MsmqIntegrationBinding 和服務地址設定
MsmqIntegrationBinding用於與傳統 MSMQ 應用程式的通訊。 為了簡化與現有 MSMQ 應用程式的互通,WCF 僅支援格式名稱尋址。 因此,使用此系結傳送的訊息必須符合 URI 配置:
msmq.formatname:<MSMQ-format-name>>
MSMQ-format-name 是 MSMQ 在 About Message Queuing 中指定的表單。
請注意,當您使用 MsmqIntegrationBinding 從佇列接收訊息時,您只能使用直接格式名稱、公用格式名稱和私人格式名稱(需要 Active Directory 整合)。 不過,建議您使用直接格式名稱。 例如,在 Windows Vista 上,使用任何其他格式名稱會造成錯誤,因為系統嘗試開啟子佇列,而該子佇列只能使用直接格式名稱開啟。
使用 MsmqIntegrationBinding 在處理 SRMP 時,不需在直接格式名稱中加入 /msmq/ 以協助 Internet Information Services(IIS)進行分派。 例如:當使用 SRMP 通訊協定處理佇列 abc 時,您應該使用 DIRECT=http://adatum.com/msmq/private$/abc 而不是 DIRECT=http://adatum.com/private$/abc。
請注意,您無法使用 net.msmq:// 尋址搭配 MsmqIntegrationBinding。 因為 MsmqIntegrationBinding 支援自由格式的 MSMQ 格式名稱尋址,因此您可以使用使用這個系結的 WCF 服務,在 MSMQ 中使用多播和通訊組清單功能。 當使用 CustomDeadLetterQueue 時,有一個例外情況是指定 MsmqIntegrationBinding。 其格式必須是 net.msmq://,類似於使用 NetMsmqBinding指定的方式。