サービス チャネル レベルのプログラミング
ここでは、Windows Communication Foundation (WCF) サービス アプリケーションを System.ServiceModel.ServiceHost とこれに関係するオブジェクト モデルを使用しないで作成する方法を説明します。
メッセージの受信
メッセージの受信と処理の準備を整えるには、次の手順に従う必要があります。
- バインディングを作成します。
- チャネル リスナをビルドします。
- チャネル リスナを開きます。
- 要求を読み取り、応答を送信します。
- すべてのチャネル オブジェクトを閉じます。
バインディングの作成
メッセージをリッスンして受信するには、まずバインディングを作成します。WCF には、複数の組み込み (つまり、システム指定の) バインディングが付属しています。これらのバインディングは、インスタンス化することによって直接使用できます。また、CustomBinding クラスをインスタンス化することにより、独自のバインディングを作成することもできます。手順 1. のコードは、この処理を実行します。
後のコード例は、System.ServiceModel.Channels.CustomBinding のインスタンスを作成し、その Elements コレクションに System.ServiceModel.Channels.HttpTransportBindingElement を追加します。Elements コレクションは、チャネル スタックを作成するために使用されるバインディング要素のコレクションです。この例では、Elements コレクションには HttpTransportBindingElement しか含まれないため、チャネル スタックは HTTP トランスポート チャネルだけを持ちます。
ChannelListener のビルド
バインディングを作成したら、System.ServiceModel.Channels.Binding.BuildChannelListener.Uri,System.ServiceModel.Channels.BindingParameterCollection) を呼び出してチャネル リスナをビルドします。型パラメータは、作成するチャネル形状です。この例では、要求/応答メッセージ交換パターンで受信メッセージをリッスンする必要があるため、System.ServiceModel.Channels.IReplyChannel を使用します。
IReplyChannel は、要求メッセージを受信し、応答メッセージを返信するために使用されます。System.ServiceModel.Channels.IReplyChannel.ReceiveRequest を呼び出すと、要求メッセージの受信と応答メッセージの返信に使用できる System.ServiceModel.Channels.IRequestChannel が返されます。
リスナを作成する際には、リッスンするネットワーク アドレス (この場合は https://localhost:8080/channelapp
) を渡します。一般に、各トランスポート チャネルは 1 つまたは複数のアドレス スキームをサポートします。たとえば、HTTP トランスポートは、http スキームと https スキームの両方をサポートします。
また、リスナを作成する際には、空の System.ServiceModel.Channels.BindingParameterCollection を渡します。バインディング パラメータは、リスナのビルド方法を制御するパラメータを渡すしくみです。この例では、このようなパラメータは使用しないため、空のコレクションを渡します。
受信メッセージのリッスン
次に、ビルドしたリスナで System.ServiceModel.ICommunicationObject.Open を呼び出し、チャネルの受け入れを開始します。System.ServiceModel.Channels.IChannelListener.AcceptChannel の動作は、トランスポートが接続指向であるか、コネクションレスであるかによって異なります。接続指向トランスポートの場合、AcceptChannel は新しい接続要求が届くまでブロックし、接続要求が届いた時点で、その新しい接続を表す新しいチャネルを返します。HTTP などのコネクションレス トランスポートの場合、AcceptChannel は、トランスポート リスナが作成する唯一のチャネルを直ちに返します。
この例では、リスナは、IReplyChannel を実装するチャネルを返します。このチャネルでメッセージを受信するには、まず、チャネルで System.ServiceModel.ICommunicationObject.Open を呼び出して通信できる状態にします。次に、メッセージが到着するまでブロックする ReceiveRequest を呼び出します。
要求の読み取りと応答の送信
ReceiveRequest が RequestContext を返すときに、その RequestMessage プロパティを使用して受信メッセージを取得します。メッセージのアクションと本文のコンテンツ (文字列であることを前提とします) を書き込みます。
応答を送信するには、新しい応答メッセージを作成します。この場合は、要求で受信した文字列データを渡します。次に、Reply を呼び出して、その応答メッセージを送信します。
オブジェクトを閉じる
リソースのリークを避けるには、通信に使用したオブジェクトが不要になったら閉じることが重要です。この例では、要求メッセージ、要求コンテキスト、チャネル、およびリスナを閉じます。
次のコード例は、チャネル リスナがメッセージを 1 つだけ受け取る基本的なサービスです。実際のサービスでは、サービスが終了するまでチャネルの受け入れとメッセージの受信を続けます。