フィルター処理
Windows Communication Foundation (WCF) フィルター処理システムは、宣言的なフィルターを使用してメッセージの照合処理と操作上の判断を行います。フィルターを使用してメッセージの一部を調べることで、そのメッセージで必要な操作を決定できます。たとえば、キュー プロセスでは、XPath 1.0 クエリを使用して既知のヘッダー優先度要素をチェックし、メッセージをキューの先頭に移動するべきかどうかを決定します。
フィルター処理システムは、特定の WCF メッセージに対して、どのフィルターのセットが true であるかを効率よく判断できる一連のクラスから構成されます。
フィルター処理システムは、WCF メッセージングの中核となるコンポーネントであり、非常に高速に動作するように設計されています。フィルターの各実装は、WCF メッセージの特定の種類の照合に対して最適化されています。
フィルター処理システムは、スレッド セーフではありません。アプリケーションは、すべてのロック セマンティクスを処理する必要があります。ただし、(スレッドに対する) マルチ リーダー/シングル ライターはサポートされています。
フィルター処理が適する場合
フィルター処理は、メッセージを適切なアプリケーション コンポーネントにディスパッチする処理の一部であり、メッセージの受信後に行われます。フィルター処理システムの設計では、WCF のいくつかのサブシステム (メッセージング、ルーティング、セキュリティ、イベント処理、およびシステム管理など) の要件に対処します。
フィルター
フィルター エンジンには、フィルターとフィルター テーブルという 2 つの主要コンポーネントが含まれます。フィルターは、ユーザーが指定した論理条件に基づいてメッセージに関する論理判定を行います。フィルターは MessageFilter クラスを実装します。
メッセージがフィルターの一致条件を満たしているかどうかを判定するには、Match メソッドを使用します。これらのメソッドの中の 1 つは、メッセージのヘッダーをテストしますが、メッセージ本文は検査できません。他のメソッドは入力パラメーターとしてメッセージ バッファーを取得し、メッセージ本文の検査が可能です。
通常、フィルターは個別にテストされるのではなく、フィルター テーブルの一部としてテストされます。フィルター テーブルは、CreateFilterTable メソッドによって作成されるジェネリック クラスです。
数種類のフィルターがあり、それぞれが特定の種類のブール型の条件での照合処理に特化されています。フィルターを作成した後に、フィルターが使用する条件を変更することはできません。フィルターの条件を変更するには、新しいフィルターを作成し、既存のフィルターを削除します。
アクション フィルター
ActionMessageFilter には、アクション文字列の一覧が含まれます。フィルターの一覧にあるアクションのいずれかが、メッセージまたはメッセージ バッファーにある Action ヘッダーに一致した場合、Match メソッドは true を返します。この一覧が空である場合、フィルターはすべてに一致するフィルターと見なされるため、メッセージまたはメッセージ バッファーはすべて一致することになり、Match メソッドは true を返します。フィルターの一覧にあるすべてのアクションが、メッセージまたはメッセージ バッファーにある Action ヘッダーに一致しない場合、Match メソッドは false を返します。メッセージにアクションがなく、フィルターの一覧が空でない場合、Match メソッドは false を返します。
エンドポイント アドレス フィルター
EndpointAddressMessageFilter は、メッセージのヘッダー コレクションに示されるエンドポイント アドレスに基づいて、メッセージおよびメッセージ バッファーのフィルター処理を行います。メッセージがこのようなフィルターを通過するには、次の条件を満たす必要があります。
フィルターのアドレス URI (Uniform Resource Identifier) がメッセージの To ヘッダーのアドレスと同じであること。
フィルターのアドレス (address.Headers コレクション) にある各エンドポイント パラメーターが、マッピング対象のヘッダーをメッセージ内で見つけることができること。メッセージまたはメッセージ バッファーの追加のヘッダーは、一致を true の状態にしておくためであれば、許容されます。
プレフィックス エンドポイント アドレス フィルター
- PrefixEndpointAddressMessageFilter は、メッセージ URI のプレフィックスとも一致できるという点を除けば、EndpointAddressMessageFilter フィルターと同じように動作します。たとえば、アドレス http://www.adatum.com を指定したフィルターは、http://www.adatum.com/userA 宛のメッセージと一致します。
XPath メッセージ フィルター
XPathMessageFilter は、XPath 式を使用して、XML ドキュメントに特定の要素、属性、テキスト、その他の XML 構文が含まれているかどうかを判定します。このフィルターは、XPath の厳密なサブセットに対して非常に効率的に処理できるように最適化されています。XML Path 言語の詳細については、W3C XML Path Language 1.0 の仕様を参照してください。
アプリケーションは通常、エンドポイントで XPathMessageFilter を使用して SOAP メッセージの内容を問い合わせ、その結果に基づいて適切なアクションを実行します。たとえば、キューの処理では、XPath クエリを使用して既知のヘッダーの優先度要素を検査し、メッセージをキューの先頭に移動するべきかどうかを決定します。
フィルター テーブル
フィルター テーブルは、キーと値のペアを保存するために使用されます。ここで、フィルターがキーであり、これに関連するデータが値になります。このフィルター データは、メッセージがフィルターに一致した場合に起きるアクションを示すために使用することができ、その型はフィルター テーブル クラスのジェネリック パラメーターになります。フィルター データは、ルーティングのルール、セッション セキュリティの状態、チャネル上のリスナーなどで構成できます。データは、データ フロー制御が必要な場所で使用できます。
フィルター テーブルは、IMessageFilterTable ジェネリック インターフェイスを実装します。
フィルター テーブルには、テーブル内のすべてのフィルターに対してメッセージとの一致を調べて、一致したフィルターまたはデータの順序付けられていないコレクションを返すメソッドがいくつかあります。メソッドの中には複数回の一致を調べて、一致したすべての項目を返すものもあります。それ以外のメソッドは 1 回だけの一致となり、1 つの項目のみを返し、フィルターが複数回一致する場合には、MultipleFilterMatchesException をスローします。
メッセージ フィルター テーブル
MessageFilterTable は、IMessageFilterTable の最も一般的な実装です。このテーブルには、すべての種類のフィルターを格納できます。
フィルターには数字による優先順位を割り当てることができます。一番大きな数が最も高い優先順位となります。複数の種類のフィルターが、同じ優先度を持つことができます。また特定の種類のフィルターが、複数の優先順位レベルに現れることもできます。
照合処理は優先順位が最も高いフィルターから開始され、ある優先順位で一致するフィルターが見つかると、それよりも優先順位の低いフィルターは検査されません。そのため、フィルターが 1 回だけ一致するメソッドを使用しているときに、あるメッセージに対してフィルターの一致が複数回発生した場合、一致フィルターの優先順位がそれぞれ異なっていれば、例外はスローされず、最も優先順位の高いフィルターが返されます。同様に、複数回フィルターが一致するメソッドでも、優先順位が最も高い一致フィルターのみが返されます。
XPath メッセージ フィルター テーブル
XPathMessageFilterTable は宣言的な XPath フィルターに最適化されているため、テーブル キーは XPathMessageFilter になります。
XPathMessageFilterTable クラスは、ほとんどのメッセージ シナリオをカバーし、XPath 1.0 の文法を完全にサポートする XPath のサブセットに合わせてマッチングを最適化します。また、効率的な並列マッチング用のアルゴリズムも最適化します。
このテーブルには、XPathNavigator および SeekableXPathNavigator 上で動作する特殊な Match メソッドがいくつかあります。SeekableXPathNavigator は、CurrentPosition プロパティを追加することで、XPathNavigator クラスを拡張します。このプロパティを使用すると、ナビゲーターを複製せずに XML ドキュメント内の位置を迅速に保存し、読み込むことができます。XPathNavigator を使用してそうした操作を行うには、大量のメモリ領域を割り当てる必要があります。WCF XPath エンジンでは、XML ドキュメントでクエリの実行中にカーソルの位置を頻繁に記録する必要があるため、SeekableXPathNavigator により、メッセージ処理にとって重要な最適化が提供されます。
顧客シナリオ
フィルター処理は、メッセージに含まれるデータに応じて、異なる処理モジュールにメッセージを送信する必要がある場合に、いつでも使用できます。一般的なのは、アクション コードに基づいてメッセージをルーティングするシナリオと、メッセージのエンドポイント アドレスに基づいてメッセージのストリームを分離化するシナリオの 2 つです。
ルーティング
エンドポイントのリスナーは、メッセージの SOAP ヘッダーに 1 つ以上のアクション コードが含まれるメッセージをリッスンします。これは、アクション コードを含む配列をコンストラクターに渡して ActionMessageFilter を作成することで実装します。このフィルターは、ListenerFactory に登録するために使用されるため、アクションがフィルター内のアクション コードのいずれかと一致するメッセージだけが特定のエンドポイントに到達します。
分離化
複数のエンドポイントがネットワーク上の同じ ServiceListener から分散している場合、メッセージを分離化し、メッセージが特定のエンドポイント アドレスに属しているかどうかを確認する唯一の方法は、EndpointAddressMessageFilter を使用することです。このフィルターは、ヘッダーに格納されている情報に対して検索を実行して、登録されているエンドポイントに向けられたメッセージを選択します。このようなフィルターを通過するのは、次の両方に対応する必要なヘッダーをすべて持っているメッセージだけです。
EndpointAddress にある URI
EndpointAddressMessageFilter で指定された EndpointAddress にある残りのエンドポイント パラメーター