カスタム メッセージ フィルター
このサンプルでは、Windows Communication Foundation (WCF) が使用するメッセージ フィルタを置き換えて、メッセージをエンドポイントにディスパッチする方法を示します。
注 : |
---|
このサンプルのセットアップ手順とビルド手順については、このトピックの最後を参照してください。 |
チャネルでの最初のメッセージがサーバーに到着すると、サーバーは、URI に関連付けられているエンドポイントがある場合に、どのエンドポイントがメッセージを受信する必要があるかを判断する必要があります。この処理は、EndpointDispatcher に関連付けられている MessageFilter オブジェクトで制御されます。
サービスの各エンドポイントには、単一の EndpointDispatcher があります。EndpointDispatcher には、AddressFilter と ContractFilter の両方があります。これら 2 つのフィルタを結合したものが、このエンドポイントに使用されるメッセージ フィルタです。
エンドポイントの AddressFilter の既定では、アドレス指定されているメッセージと、サービス エンドポイントの EndpointAddress に一致するアドレスを照合します。エンドポイントの ContractFilter の既定では、受信メッセージのアクションを検査して、サービス エンドポイントのコントラクトの操作のいずれかのアクション (対象になるのは IsInitiating=true のアクションだけです) に対応するアクションが含まれるメッセージを照合します。その結果、エンドポイントのフィルタの既定で一致と見なされるのは、メッセージの To ヘッダーがエンドポイントの EndpointAddress に一致し、メッセージのアクションがエンドポイントの操作のいずれかのアクションと一致するという、2 つの条件がどちらも満たされる場合だけです。
これらのフィルタは、動作を使用して変更できます。サンプルのサービスは、次のように IEndpointBehavior を作成して、EndpointDispatcher の AddressFilter と ContractFilter を置き換えます。
class FilteringEndpointBehavior : IEndpointBehavior …
2 つのアドレス フィルタは、次のように定義されます。
// 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
は構成可能になり、2 つの異なるバリエーションを設定できます。
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
の 1 つを次のように参照します。
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
クライアント アプリケーションの実装は単純で、URI の値を 2 番目の (via) パラメータとして CreateChannel に渡すことによって、2 つのチャネルをサービスの URI に作成し、各チャネルに 1 つのメッセージを送信します。ただし、チャネルごとに異なるエンドポイント アドレスが使用されます。この結果、次のクライアントの出力に示すように、クライアントからの送信メッセージにはそれぞれ異なる宛先が指定され、サーバーはこれに応じて応答します。
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" />
注 : |
---|
サンプルは、既にコンピューターにインストールされている場合があります。続行する前に、次の (既定の) ディレクトリを確認してください。
<InstallDrive>:\WF_WCF_Samples
このディレクトリが存在しない場合は、「.NET Framework 4 向けの Windows Communication Foundation (WCF) および Windows Workflow Foundation (WF) のサンプル」にアクセスして、Windows Communication Foundation (WCF) および WF のサンプルをすべてダウンロードしてください。このサンプルは、次のディレクトリに格納されます。
<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\MessageFilter
|
サンプルを設定、ビルド、および実行するには
ソリューションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。
単一コンピュータ構成でサンプルを実行するには、「Running the Windows Communication Foundation Samples」の手順に従います。
複数コンピュータ構成でサンプルを実行するには、「Running the Windows Communication Foundation Samples」の手順に従い、Client.cs の次の行を変更します。
Uri serviceVia = new Uri("https://localhost/ServiceModelSamples/service.svc");
つまり、localhost をサーバー名に置き換えます。
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");