MessageFilter 範例示範如何取代 Windows Communication Foundation (WCF) 用來將訊息分派至端點的訊息篩選。
備註
此範例的安裝程式和建置指示位於本主題結尾。
當通道上的第一個訊息到達伺服器時,伺服器必須判斷與該 URI 相關聯的端點應該接收訊息的哪個(如果有的話)。 此程式是由 MessageFilter 附加至 EndpointDispatcher的物件所控制。
服務的每個端點都有一個EndpointDispatcher。 EndpointDispatcher同時具有 AddressFilter 和 ContractFilter。 這兩個篩選條件的聯集是用於該端點的訊息篩選。
根據預設,AddressFilter 端點將匹配任何被尋址至符合服務端點的 EndpointAddress 位址的訊息。 根據預設,ContractFilter 端點會檢查傳入訊息的動作,並將傳入訊息與服務端點合約作業的一個動作相符(只會考慮IsInitiating
=true
動作)。 因此,根據預設,只有在訊息的 To 標頭是端點的 EndpointAddress,且訊息的動作符合其中一個端點操作的動作時,端點的篩選器才會匹配。
您可以使用行為來變更這些篩選。 在範例中,服務會建立IEndpointBehavior,以取代AddressFilter上的ContractFilter和EndpointDispatcher。
class FilteringEndpointBehavior : IEndpointBehavior
{
//...
}
定義兩個地址篩選:
// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter { }
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter { }
FilteringEndpointBehavior
可設定 ,並允許兩個不同的變化。
public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }
變化 1 只會比對包含 'e' 的位址(但具有任何動作),而變化 2 只比對缺少 'e' 的位址:
if (Variation == 1)
return new FilteringEndpointBehavior(
new MatchEAddressFilter(), new MatchAllMessageFilter());
else
return new FilteringEndpointBehavior(
new MatchNoEAddressFilter(), new MatchAllMessageFilter());
在組態檔中,服務會註冊新的行為:
<extensions>
<behaviorExtensions>
<add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
</behaviorExtensions>
</extensions>
然後服務會為每個版本建立endpointBehavior
組態。
<endpointBehaviors>
<behavior name="endpoint1">
<filteringEndpointBehavior variation="1" />
</behavior>
<behavior name="endpoint2">
<filteringEndpointBehavior variation="2" />
</behavior>
</endpointBehaviors>
最後,服務的端點會參考其中 behaviorConfigurations
一個 :
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
用戶端應用程式的實作很簡單;它會為服務的 URI 建立兩個通道(將該值當做第二個 (via
) 參數 CreateChannel(EndpointAddress) 傳入,並在每個通道上傳送單一訊息,但會針對每個通道使用不同的端點位址。 因此,客戶端發送的訊息具有不同的收件人,伺服器會據此回應,如客戶端的輸出所示:
Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.
Sending message to urn:a...
Hello
切換伺服器組態檔中的變異會導致過濾器被交換,用戶端將會看到相反的行為(訊息傳送到 urn:e
成功,而傳送到 urn:a
則失敗)。
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
要設定、建置和執行範例,請執行以下步驟:
若要建置解決方案,請遵循 建置 Windows Communication Foundation 範例中的指示。
若要在單一計算機設定中執行範例,請遵循 執行 Windows Communication Foundation 範例中的指示。
若要在跨計算機組態中執行範例,請遵循執行 Windows Communication Foundation 範例 中的指示,並在 Client.cs中變更下列這一行。
Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
以伺服器名稱取代localhost。
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");