TCP や名前付きパイプなどのストリーム指向トランスポートは、クライアントとサーバー間のバイトの連続ストリームで動作します。 このストリームは、 Stream オブジェクトによって実現されます。 ストリーム のアップグレードでは、クライアントはオプションのプロトコル 層をチャネル スタックに追加し、通信チャネルのもう一方の端に要求します。 ストリームアップグレードは、元の Stream オブジェクトをアップグレードされたオブジェクトに置き換えることで構成されます。
たとえば、トランスポート ストリームの上に圧縮ストリームを直接構築できます。 この場合、元のトランスポート Stream は、元のトランスポートを圧縮で包むトランスポートに置き換えられます。
複数のストリーム アップグレードを適用できます。各アップグレードは、前のアップグレードをラップします。
ストリーム アップグレードのしくみ
ストリーム アップグレード プロセスには 4 つのコンポーネントがあります。
アップグレード ストリーム イニシエーター がプロセスを開始します。実行時に、チャネル トランスポート層をアップグレードするために、接続のもう一方の端への要求を開始できます。
アップグレード ストリーム Acceptor はアップグレードを実行します。実行時に、他のマシンからアップグレード要求を受信し、可能であればアップグレードを受け入れます。
アップグレード プロバイダー は、クライアント上に イニシエーター を作成し、サーバー上に アクセプター を作成します。
ストリーム アップグレード Binding 要素 がサービスとクライアントのバインドに追加され、実行時にプロバイダーが作成されます。
複数のアップグレードの場合、イニシエーターとアクセプターは状態マシンをカプセル化して、各開始に対して有効なアップグレード遷移を強制します。
ストリーム アップグレードを実装する方法
Windows Communication Foundation (WCF) には、実装できる 4 つの abstract
クラスが用意されています。
カスタム ストリームアップグレードを実装するには、次の操作を行います。 この手順では、クライアント コンピューターとサーバー コンピューターの両方に最小限のストリーム アップグレード プロセスを実装します。
StreamUpgradeInitiator を実装するクラスを作成します。
アップグレードするストリームを取り込む InitiateUpgrade メソッドをオーバーライドし、アップグレードされたストリームを返します。 このメソッドは同期的に動作します。アップグレードを非同期的に開始する類似の方法があります。
GetNextUpgradeメソッドをオーバーライドして、追加のアップグレードを確認します。
StreamUpgradeAcceptor を実装するクラスを作成します。
アップグレードするストリームを取り込む AcceptUpgrade メソッドをオーバーライドし、アップグレードされたストリームを返します。 このメソッドは同期的に動作します。アップグレードを非同期的に受け入れる類似の方法があります。
CanUpgradeメソッドをオーバーライドして、要求されたアップグレードがアップグレード プロセスのこの時点でこのアップグレード アクセプターでサポートされているかどうかを判断します。
StreamUpgradeProviderを実装するクラスを作成します。 CreateUpgradeAcceptorメソッドとCreateUpgradeInitiatorメソッドをオーバーライドして、手順 2 と 1 で定義されているアクセプターとイニシエーターのインスタンスを返します。
StreamUpgradeBindingElement を実装するクラスを作成します。
クライアントの BuildClientStreamUpgradeProvider メソッドとサービスの BuildServerStreamUpgradeProvider メソッドをオーバーライドします。
クライアントの BuildChannelFactory メソッドとサービスの BuildChannelListener メソッドをオーバーライドして、アップグレードバインド要素を BindingParametersに追加します。
サーバーおよびクライアント コンピューター上のバインドに新しいストリーム アップグレード バインド要素を追加します。
セキュリティのアップグレード
セキュリティ アップグレードの追加は、一般的なストリーム アップグレード プロセスの特殊なバージョンです。
WCF には、ストリーム セキュリティをアップグレードするための 2 つのバインディング要素が既に用意されています。 トランスポート レベルのセキュリティの構成は、 WindowsStreamSecurityBindingElement と、カスタム バインドに構成して追加できる SslStreamSecurityBindingElement によってカプセル化されます。 これらのバインド要素は、クライアントとサーバー ストリームのアップグレード プロバイダーを構築する StreamUpgradeBindingElement クラスを拡張します。 これらのバインド要素には、 public
されていない特殊なセキュリティ ストリーム アップグレード プロバイダー クラスを作成するメソッドがあるため、これら 2 つのケースでは、バインド要素をバインドに追加するだけで済みます。
上記の 2 つのバインディング要素が満たしていないセキュリティ シナリオでは、上記のイニシエーター、アクセプター、プロバイダーの基底クラスから 3 つのセキュリティ関連の abstract
クラスが派生します。
セキュリティ ストリームのアップグレードを実装するプロセスは、前と同じですが、これら 3 つのクラスから派生する違いがあります。 これらのクラスの追加プロパティをオーバーライドして、ランタイムにセキュリティ情報を提供します。
複数のアップグレード
追加のアップグレード要求を作成するには、上記のプロセスを繰り返します。 StreamUpgradeProvider 要素とバインド要素の追加の拡張機能を作成します。 バインド要素をバインドに追加します。 追加のバインド要素は、バインドに追加された最初のバインド要素から開始して順番に処理されます。 BuildChannelFactoryおよびBuildChannelListenerでは、各アップグレード プロバイダーは、既存のアップグレード バインド パラメーターに自身を重ねて配置する方法を決定できます。 その後、既存のアップグレード バインド パラメーターを新しい複合アップグレード バインド パラメーターに置き換える必要があります。
または、1 つのアップグレード プロバイダーで複数のアップグレードをサポートすることもできます。 たとえば、セキュリティと圧縮の両方をサポートするカスタム ストリーム アップグレード プロバイダーを実装できます。 次の手順を実行します。
サブクラス StreamSecurityUpgradeProvider イニシエーターとアクセプターを作成するプロバイダー クラスを記述します。
StreamSecurityUpgradeInitiatorをサブクラス化して、圧縮ストリームとセキュア ストリームのコンテンツ タイプを順番に返すように、GetNextUpgrade メソッドをオーバーライドします。
StreamSecurityUpgradeAcceptor メソッドのカスタム コンテンツ タイプを理解するCanUpgradeをサブクラス化します。
ストリームは、 GetNextUpgrade と CanUpgradeへの各呼び出しの後にアップグレードされます。