次の方法で共有


トランスポート : WSE 3.0 TCP 相互運用性

Download sample

WSE 3.0 TCP 相互運用性トランスポートのサンプルでは、TCP 二重セッションを Windows Communication Foundation (WCF) カスタム トランスポートとして実装する方法を示します。さらに、チャネル レイヤの拡張機能を使用して、ネットワーク経由で既存の配置システムと連結する方法も示します。この WCF カスタム トランスポートを作成する方法を、次の手順に示します。

  1. まず TCP ソケットを使用して、DIME フレームを使用する IDuplexSessionChannel のクライアント実装とサーバー実装を作成し、メッセージ境界を決定します。

  2. WSE TCP サービスに接続してクライアント IDuplexSessionChannel 経由でフレーム メッセージを送信する、チャネル ファクトリを作成します。

  3. 受信 TCP 接続を受け入れて対応するチャネルを作成するチャネル リスナを作成します。

  4. ネットワーク固有の例外が、CommunicationException の適切な派生クラスに標準化されていることを確認します。

  5. チャネル スタックにカスタム トランスポートを追加するバインディング要素を追加します。詳細については、「Adding a Binding Element」を参照してください。

IDuplexSessionChannel の作成

WSE 3.0 TCP 相互運用性トランスポートを作成するには、まず、Socket 上に IDuplexSessionChannel の実装を作成します。WseTcpDuplexSessionChannel は、ChannelBase から派生します。メッセージ送信のロジックは、(1) メッセージをバイトにエンコードし、(2) それらのバイトをフレーム化してネットワーク上に送信するという、2 つの主要部分で構成されます。

ArraySegment<byte> encodedBytes = EncodeMessage(message);

WriteData(encodedBytes);

さらに、Send() 呼び出しが IDuplexSessionChannel の順序の保証を保持し、基になるソケットに対する呼び出しが正しく同期されるように、ロックを取得します。

WseTcpDuplexSessionChannel は、Message と byte[] を相互に変換するために、MessageEncoder を使用します。WseTcpDuplexSessionChannel はトランスポートなので、チャネルが構成されたリモート アドレスの適用も行います。EncodeMessage は、この変換ロジックを次のようにカプセル化します。

this.RemoteAddress.ApplyTo(message);

return encoder.WriteMessage(message, maxBufferSize, bufferManager);

Message がバイトにエンコードされたら、ネットワーク上に送信する必要があります。これを行うには、メッセージ境界を定義するシステムが必要です。WSE 3.0 は DIME のバージョンをフレーム プロトコルとして使用します。WriteData はこのフレーム ロジックをカプセル化して、byte[] を一連の DIME レコードにラップします。

メッセージ受信用のロジックは、上記のロジックとほぼ同じです。複雑な点は、主に、読み取られたソケットによって返されるバイトが、要求されたバイトよりも少ない場合があることに関する処理です。メッセージを受信するには、WseTcpDuplexSessionChannel がネットワーク経由でないバイトを読み取って DIME フレームを復号化し、その後MessageEncoder を使用して byte[] を Message に変換します。

基本の WseTcpDuplexSessionChannel は、接続されたソケットを受信することを前提とします。この基本クラスでは、ソケットのシャットダウンが処理されます。ソケットの終了と連動する場所は、次の 3 つです。

  1. OnAbort -- ソケットを異常終了します (強制終了)。

  2. On[Begin]Close -- ソケットを正常に終了します (正常終了)。

  3. session.CloseOutputSession -- 送信データ ストリームをシャットダウンします (半終了)。

チャネル ファクトリ

TCP トランスポートを記述する次の手順では、クライアント チャネルでの IChannelFactory の実装を作成します。

  • WseTcpChannelFactoryChannelFactoryBase<IDuplexSessionChannel> から派生します。このファクトリは、次のように OnCreateChannel をオーバーライドして、クライアント チャネルを作成します。

protected override IDuplexSessionChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via)

{

return new ClientWseTcpDuplexSessionChannel(encoderFactory, bufferManager, remoteAddress, via, this);

}

  • ClientWseTcpDuplexSessionChannel は基本 WseTcpDuplexSessionChannel にロジックを追加して、channel.Open のときに TCP サーバーに接続します。まず、ホスト名を解決して IP アドレスに変換します。

hostEntry = Dns.GetHostEntry(Via.Host);

  • そして、次のようにループ内で最初に利用可能な IP アドレスに接続されます。

IPAddress address = hostEntry.AddressList[i];

socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

socket.Connect(new IPEndPoint(address, port));

  • チャネル コントラクトの一部として、CommunicationExceptionSocketException など、ドメイン固有の任意の例外をラップします。

チャネル リスナ

TCP トランスポートを記述する次の手順では、サーバー チャネルを受け入れるための IChannelListener の実装を作成します。

  • WseTcpChannelListenerChannelListenerBase<IDuplexSessionChannel> から派生し、On[Begin]Open と On[Begin]Close をオーバーライドしてリッスン ソケットの有効期間を制御します。OnOpen で、IP_ANY でリッスンするソケットを作成します。より高度な実装では、同様に IPv6 でリッスンする 2 つ目のソケットを作成できます。そのような実装では、IP アドレスをホスト名で指定することもできます。

IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, uri.Port);

this.listenSocket = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

this.listenSocket.Bind(localEndpoint);

this.listenSocket.Listen(10);

新しいソケットが受け入れられると、サーバー チャネルがこのソケットで初期化されます。すべての入出力は既に基本クラスに実装されているので、このチャネルでソケットの初期化に対応します。

バインディング要素の追加

ファクトリおよびチャネルを作成したら、バインディングを使用してそれらを ServiceModel ランタイムに開示する必要があります。バインディングは、サービス アドレスに関連する通信スタックを表すバインディング要素のコレクションです。スタックの各要素は、バインディング要素によって表されます。

このサンプルでは、バインディング要素は WseTcpTransportBindingElement で、TransportBindingElement から派生しています。IDuplexSessionChannel がサポートされており、次のメソッドをオーバーライドして、バインディングに関連したファクトリを作成します。

public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)

{

return (IChannelFactory<TChannel>)(object)new WseTcpChannelFactory(this, context);

}

public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)

{

return (IChannelListener<TChannel>)(object)new WseTcpChannelListener(this, context);

}

また、この要素には、BindingElement を複製したり、スキーム (wse.tcp) を返したりするためのメンバも含まれます。

WSE TCP テスト コンソール

このサンプルのトランスポートを使用するテスト コードは、TestCode.cs で使用できます。WSE TcpSyncStockService サンプルの設定方法を次の手順に示します。

このテスト コードでは、MTOM をエンコーディングとして使用し、WseTcpTransport をトランスポートとして使用するカスタム バインディングを作成します。さらに、AddressingVersion を、次のように WSE 3.0 に準拠するように設定します。

CustomBinding binding = new CustomBinding();

MtomMessageEncodingBindingElement mtomBindingElement = new MtomMessageEncodingBindingElement();

mtomBindingElement.MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;

binding.Elements.Add(mtomBindingElement);

binding.Elements.Add(new WseTcpTransportBindingElement());

テスト コードは 2 つのテストで構成されます。1 つ目のテストは、WSE 3.0 WSDL から生成されたコードを使用して型指定のあるクライアントを設定します。2 つ目のテストは、メッセージを直接チャネル API 上に送信することによって、WCF をクライアントとサーバーの両方として使用します。

このサンプルを実行すると、次の出力が予測されます。

クライアント

Calling soap://stockservice.contoso.com/wse/samples/2003/06/TcpSyncStockService

Symbol: FABRIKAM
        Name: Fabrikam, Inc.
        Last Price: 120

Symbol: CONTOSO
        Name: Contoso Corp.
        Last Price: 50.07
Press enter.

Received Action: http://SayHello
Received Body: to you.
Hello to you.
Press enter.

Received Action: http://NotHello
Received Body: to me.
Press enter.

サーバー

Listening for messages at soap://stockservice.contoso.com/wse/samples/2003/06/TcpSyncStockService

Press any key to exit when done...

Request received.
Symbols:
        FABRIKAM
        CONTOSO

サンプルを設定、ビルド、および実行するには

  • このサンプルを実行するには、WSE 3.0 と WSE TcpSyncStockService サンプルがインストールされている必要があります。WSE 3.0 は、MSDN からダウンロードできます。
Noteメモ :

Windows Server 2008 では WSE 3.0 がサポートされていないため、このオペレーティング システムでは TcpSyncStockService サンプルをインストールすることも、実行することもできません。

  1. TcpSyncStockService サンプルをインストールしたら、次の手順を実行します。

    1. Visual Studio で TcpSyncStockService を開きます (TcpSyncStockService サンプルは WSE 3.0 と共にインストールされます。このサンプル コードの一部ではありません)。

    2. StockService プロジェクトをスタートアップ プロジェクトとして設定します。

    3. StockService プロジェクトの StockService.cs を開き、StockService クラスの Policy 属性をコメント化します。これにより、サンプルのセキュリティが無効になります。WCF は WSE 3.0 のセキュリティ保護されたエンドポイントと相互運用できますが、このサンプルではカスタム TCP トランスポートに重点を置くため、セキュリティを無効にします。

    4. F5 キーを押して、TcpSyncStockService を開始します。サービスが新しいコンソール ウィンドウで開始します。

    5. Visual Studio で、この TCP トランスポートのサンプルを開きます。

    6. TestCode.cs 内の hostname 変数の値を、TcpSyncStockService が実行されているコンピュータ名に一致するように更新します。

    7. F5 キーを押して、TCP トランスポートのサンプルを開始します。

    8. TCP トランスポートのテスト クライアントが、新しいコンソールで開始します。クライアントはサービスに株価情報を要求し、その結果がコンソール ウィンドウに表示されます。

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.