次の方法で共有


カスタム エンコーダ

このトピックでは、カスタム エンコーダを作成する方法について説明します。

Windows Communication Foundation (WCF) では "バインディング" を使用して、エンドポイントどうしがネットワーク経由でデータを転送する方法を指定します**。バインディングは、一連の "バインディング要素" で構成されます**。バインディングには、セキュリティなどのオプションのプロトコル バインディング要素、必須のメッセージ エンコーダのバインディング要素、および必須のトランスポートのバインディング要素が含まれます**。メッセージ エンコーダは、メッセージ エンコーディング バインディング要素で表されます。WCF に含まれるメッセージ エンコーダは、バイナリ、MTOM (Message Transmission Optimization Mechanism)、およびテキストの 3 つです。

メッセージ エンコーディング バインディング要素は、送信する Message をシリアル化してそれをトランスポートに渡すか、シリアル化された形式のメッセージをトランスポートから受信して、それをプロトコル層 (ある場合) またはアプリケーション (プロトコル層がない場合) に渡します。

メッセージ エンコーダは、Message インスタンスと物理メッセージ形式を相互に変換します。エンコーダは、チャネル スタックのトランスポート層の上に位置すると説明されていますが、トランスポート層の内部に存在します。トランスポート (HTTP など) は、トランスポート標準の要件に従ってメッセージの書式設定を行います。エンコーダ (テキスト XML など) は、単にメッセージのエンコードを行います。

既存のクライアントまたはサーバーに接続する場合、特定のメッセージ エンコーディングを使用する選択ができない場合があります。ただし、WCF サービスは、それぞれが異なるメッセージ エンコーダを使用する複数のエンドポイントからアクセスできるようにすることができます。1 つのエンコーダでサービスの対象ユーザー全体を網羅しない場合、複数のエンドポイントにサービスを公開することを検討します。これによりクライアント アプリケーションはそのアプリケーションに最も適したエンドポイントを選択できます。複数のエンドポイントを使用することにより、さまざまなメッセージ エンコーダの利点を他のバインディング要素と組み合わせることが可能になります。

システム指定のエンコーダ

WCF では、最も一般的なアプリケーション シナリオに合わせて設計されたシステム既定のバインディングがいくつか用意されています。これらのバインディングは、それぞれトランスポート、メッセージ エンコーダ、その他のオプション (セキュリティなど) を組み合わせます。このトピックでは、WCF に含まれる TextBinaryMTOM メッセージ エンコーダの拡張方法、つまり独自のカスタム エンコーダの作成方法について説明します。テキスト メッセージ エンコーダは、通常の XML のエンコーディングに加えて、SOAP のエンコーディングもサポートします。テキスト メッセージ エンコーダの通常の XML エンコーディング モードは、テキスト ベースの SOAP エンコーディングと区別するために、POX ("Plain Old XML") エンコーダと呼ばれます。

システム定義のバインディングにより提供されるバインディング要素の組み合わせ詳細については、 、「トランスポートの選択」の対応するセクションを参照してください。

システム標準のエンコーダの操作方法

エンコーディングは、MessageEncodingBindingElement からの派生クラスを使用してバインディングに追加します。

WCF では、テキスト、バイナリ、および MTOM (Message Transmission Optimization Mechanism) のエンコーディングに対応した MessageEncodingBindingElement クラスから派生した次の種類のバインディング要素が提供されます。

  • TextMessageEncodingBindingElement : 相互運用性は最も高く、効率は最も低い、XML メッセージ用のエンコーダ。Web サービスまたは Web サービス クライアントは、一般に、テキスト形式の XML を認識できます。ただし、大きいブロックのバイナリ データをテキストとして転送するのは効率的ではありません。
  • BinaryMessageEncodingBindingElement : バイナリベースの XML メッセージで使用される、文字エンコーディングおよびメッセージのバージョン管理を指定するバインディング要素を表します。これは最も効率的なエンコーディング オプションですが、WCF エンドポイントでしかサポートされないため、相互運用性は最も低くなります。
  • MTOMMessageEncodingBindingElement : Message Transmission Optimization Mechanism (MTOM) エンコードを使用するメッセージの文字エンコードおよびメッセージ バージョン管理を指定するバインディング要素を表します。MTOM は、WCF メッセージでのバイナリ データの転送に有効なテクノロジです。MTOM エンコーダは、効率と相互運用性のバランスを取ろうとします。MTOM エンコーディングは、ほとんどの XML をテキスト形式で転送しますが、大きいサイズのバイナリ データ ブロックはテキストに変換せずにそのまま転送することによって最適化します。

バインディング要素は、バイナリ、MTOM、またはテキストの MessageEncoderFactory を作成します。ファクトリは、バイナリ、MTOM、またはテキストの MessageEncoder を作成します。通常、インスタンスは 1 つだけあります。ただし、セッションを使用すると、異なるエンコーダを各セッションに提供できます。バイナリ エンコーダでは、これを利用して動的ディクショナリ (XML インフラストラクチャを参照) を調整します。

ReadMessage メソッドと WriteMessage メソッドは、エンコーダのコアです。このメソッドは、ストリームまたは Byte 配列からのメッセージの読み取りに対応します。バイト配列は、トランスポートをバッファ モードで操作している場合に使用されます。メッセージはストリームに常に書き込まれます。トランスポートでメッセージをバッファする必要がある場合は、バッファリングを行うストリームが提供されます。

残りのメンバは、サポート コンテンツ、メディアの種類、および MessageVersion を処理します。トランスポートは、このエンコーダ メソッドを呼び出して、受信メッセージがデコード可能かどうかをテストするか、または送信メッセージがこのエンコーダに対して有効かどうかを決定します。

3 つのそれぞれのエンコーダ実装は、特定のエンコーディングに関連するプロパティを追加し、完全に構成可能です。また、エンコーダは、安全な既定値を持つリーダーのクォータも公開しています。クォータの詳細については、XML インフラストラクチャを参照してください。

システム標準のエンコーダの機能

システム標準のエンコーダは多くの機能を提供します。

プール

各エンコーダ実装は、可能な限りプールを試みます。マネージ コードのパフォーマンスを向上するには、割り当てを減らすことが重要です。このプールを実現するには、実装で SynchronizedPool クラスを使用します。C# ファイルには、このクラスで使用する追加の最適化に関する記述を含めます。

メッセージごとに新しい XmlDictionaryReader および XmlDictionaryWriter インスタンスを割り当てるのを避けるため、これらのインスタンスをプールして再初期化します。リーダーについては、Close() の呼び出し時に OnClose コールバックでリーダーが再利用されます。また、エンコーダでは、メッセージを作成するときに使用するいくつかのメッセージ状態オブジェクトが再利用されます。このプールのサイズは、MessageEncodingBindingElement から派生した 3 つの各クラスの MaxReadPoolSize プロパティと MaxWritePoolSize プロパティによって構成可能です。

バイナリ エンコーディング

バイナリ エンコーディングでセッションを使用する場合、動的ディクショナリの文字列をメッセージの受信者と通信する必要があります。これを行うには、メッセージのプレフィックスに動的ディクショナリの文字列を指定します。受信側では、その文字列を取り除いて、セッションに追加し、メッセージ処理を行います。ディクショナリの文字列を正しく渡すには、トランスポートをバッファする必要があります。

文字列は、内部 AddSessionInformationToMessage メソッドによってメッセージに追加されます。文字列は、メッセージの先頭に UTF-8 として追加され、その長さがプレフィックスに指定されます。次にディクショナリ ヘッダー全体のプレフィックスにそのデータ長が指定されます。内部 ExtractSessionInformationFromMessage メソッドにより逆操作が実行されます。

動的ディクショナリ キーの処理に加え、バッファされセッションの多いメッセージが独自の方法で受信されます。ドキュメントでリーダーを作成して処理する代わりに、バイナリ エンコーダは、内部 MessagePatterns クラスを使用してバイナリ ストリームを分解します。つまり、WCF で作成されたほとんどのメッセージには、特定の順序で表された特定セットのヘッダーがあります。想定を基にしたパターン システムによりメッセージは分割されます。成功した場合は、XML の解析を行わずに MessageHeaders オブジェクトを初期化します。成功しなかった場合は、標準の方法に戻ります。

MTOM エンコーディング

MtomMessageEncodingBindingElement クラスには、MaxBufferSize という追加の構成プロパティがあります。これには、メッセージ読み取り中にバッファできるデータ量の上限が設けられています。すべての MIME パートを 1 つのメッセージに再アセンブルするために、XML 情報セット (Infoset) または他の MIME パートをバッファすることが必要な場合もあります。

HTTP を正しく操作するために、内部 MTOM メッセージ エンコーダのクラスでは、GetContentType (内部) や WriteMessage (パブリックで、オーバーライド可能) の内部 API がいくつか用意されています。HTTP ヘッダーの値を MIME ヘッダーの値と一致させるには、多くの通信を行う必要があります。

内部的に、MTOM メッセージ エンコーダは、WCF のテキスト リーダーを使用するので、テキスト エンコーダに似ています。主な違いは、Base-64 エンコーディングに変換せずにメッセージ バイトに埋め込むことで、大きいサイズのバイナリ (バイナリ ラージ オブジェクト (BLOB) と呼びます) を最適化する点です。代わりに、この BLOB は抽出され、MIME 添付として参照されます。

独自のエンコーダの作成

独自のカスタム メッセージ エンコーダを実装するには、次の抽象基本クラスのカスタム実装を提供する必要があります。

  • MessageEncoder
  • MessageEncoderFactory
  • MessageEncodingBindingElement

メッセージのメモリ内表現からストリームに書き込むことのできる表現への変換は、 MessageEncoder クラスにカプセル化されており、このクラスは、特定の種類の XML エンコーディングをサポートする XML リーダーおよび XML ライタに対するファクトリとして機能します。

  • オーバーライドを必要とする、このクラスの主要なメソッドを次に示します。
  • WriteMessageMessage オブジェクトを受け取り、それを Stream オブジェクトに書き込みます。
  • ReadMessageStream オブジェクトと最大ヘッダー サイズを受け取り、Message オブジェクトを返します。

これらのメソッドに記述するコードは、標準トランスポート プロトコルとカスタマイズしたエンコーディングの間の変換処理です。

次に、カスタム エンコーダを作成するファクトリ クラスをコーディングする必要があります。Encoder をオーバーライドして、独自のカスタム MessageEncoder のインスタンスを返します。

次に、CreateMessageEncoderFactory メソッドをオーバーライドしてこのファクトリのインスタンスを返すようにすることで、サービスまたはクライアントの構成に使用されるバインディング要素スタックにカスタム MessageEncoderFactory を接続します。

WCF には、この処理を説明する 2 つの例がサンプル コードと共に用意されています。「Custom Message Encoder: Custom Text Encoder」および「Custom Message Encoder: Compression Encoder」を参照してください。

関連項目

リファレンス

MessageEncodingBindingElement
MessageEncoderFactory
MessageEncoder

概念

データ転送のアーキテクチャの概要
メッセージ エンコーダを選択する
トランスポートの選択