チャネル
チャネルは、アプリケーション ドメイン間、プロセス間、またはコンピュータ間のリモート処理境界を越えて、アプリケーション相互の間でメッセージを転送するオブジェクトです。チャネルは、着信するメッセージをエンドポイントでリッスンしたり、他のエンドポイントへのメッセージを送信したりできます。これにより、チャネルの反対側のエンドで共通言語ランタイムが実行されていない場合でも、さまざまなプロトコルをプラグインできます。
チャネルは、ChannelName や ChannelPriority などの情報プロパティを提供する IChannel インターフェイスを実装する必要があります。特定のポートで特定のプロトコルをリッスンするようにデザインされたチャネルは IChannelReceiver を実装し、情報を送信するようにデザインされたチャネルは IChannelSender を実装します。TcpChannel オブジェクトおよび HttpChannel オブジェクトは、これらのインターフェイスを両方とも実装するため、情報の送信または受信に使用できます。
チャネルをリモート処理インフラストラクチャに登録するには、次の方法があります。
リモート処理可能オブジェクトを公開する場合は、サーバー オブジェクトを登録する前に ChannelServices.RegisterChannel を呼び出します。
リモート処理可能オブジェクトの機能を利用する場合は、サーバー オブジェクトのインスタンスを生成する前に RegisterChannel を呼び出します。
チャネルは、リモート処理構成ファイルから読み込むこともできます。詳細については、「構成」を参照してください。
クライアント側では、メッセージはクライアント コンテキスト チェーンを通過した後、クライアント チャネル シンク チェーンに渡されます。最初のチャネル シンクは通常はフォーマッタ シンクで、これはメッセージをシリアル化してストリームに変換し、ストリーム化されたメッセージはチャネル シンク チェーンを通ってクライアント トランスポート シンクに渡されます。クライアント トランスポート シンクはこのストリームをネットワークに送出します。
サーバー側では、サーバー トランスポート シンクがネットワークから要求を読み込み、要求ストリームをサーバー チャネル シンク チェーンに渡します。このチェーンの最後にあるサーバー フォーマッタ シンクは、要求を逆シリアル化してメッセージに変換します。次に、このメッセージをリモート処理インフラストラクチャに渡します。チャネル シンクの詳細については、「シンクとシンク チェーン」を参照してください。
チャネルの規則
クライアントがリモート オブジェクトのメソッドを呼び出すと、パラメータが、呼び出しに関連するその他の詳細情報と共に、チャネルを通じてリモート オブジェクトに転送されます。呼び出しからの結果も同じ方法で返されます。クライアントはリモート オブジェクトと通信するために、サーバーで登録されているチャネルをどれでも選択できます。それにより開発者は、目的に最も適したチャネルを選択できます。また、既存のチャネルをカスタマイズしたり、別の通信プロトコルを使用する新しいチャネルを構築したりできます。チャネル選択は、次の規則に従います。
リモート オブジェクトを呼び出す前に、少なくとも 1 つのチャネルがサーバー上のリモート処理システムに登録されている必要があります。チャネルは、オブジェクトが登録される前に登録されている必要があります。クライアント上でチャネルが登録されていない場合、リモート処理システムは外部宛ての呼び出しを送信するために、チャネルを選択または生成します。
メモ : クライアントがコールバック関数を予期している場合は、リッスンするチャネルがクライアント上で登録され、サーバーが互換チャネルを使用するように構成されている必要があります。
チャネルは、アプリケーション ドメインごとに登録されます。1 つのプロセスに複数のアプリケーション ドメインを含めることができます。プロセスが終了すると、そのプロセスによって登録されたすべてのチャネルは自動的に破棄されます。
チャネル名は、アプリケーション ドメイン内で一意である必要があります。たとえば、既定のチャネルには名前が付けられているため、1 つのアプリケーション ドメインに 2 つの HttpChannel オブジェクトを登録するには、その前にチャネルの名前を変更しておく必要があります。名前を変更して登録する C# のコード例を次に示します。
IDictionary prop = new Hashtable(); prop["name"] = "http1"; prop["port"] = "9001"; ChannelServices.RegisterChannel(new HttpChannel(prop, null, null));
特定のポートでリッスンするチャネルを 2 回以上登録することはできません。チャネルはアプリケーション ドメインごとに登録されますが、同じコンピュータ上の異なるアプリケーション ドメインは、同じポートでリッスンする同じチャネルを登録できません。
ポートが使用できるかどうか不明な場合、チャネルのポートを 0 (ゼロ) に構成すると、リモート処理システムが使用可能なポートを自動的に選択します。
クライアントは、登録されている任意のチャネルを使用して、リモート オブジェクトと通信できます。リモート処理システムは、クライアントがリモート オブジェクトへの接続を試行したときに、そのオブジェクトが正しいチャネルに接続されるようにします。クライアントは、リモート オブジェクトとの通信を試みる前に、ChannelServices.RegisterChannel を呼び出す必要があります。オブジェクトがコールバック関数を使用するときは、クライアントはチャネルとポートを登録する必要があります。
クライアントがプロキシのメソッドを呼び出すと、その呼び出しは受け取られてメッセージにバンドルされ、RealProxy クラスのインスタンスに渡されます。RealProxy クラスは、そのメッセージを処理するためにメッセージ シンクに転送します。メッセージ シンクは、リモート オブジェクトによって登録されたチャネルとの接続を確立し、そのチャネルを通じてメッセージを本来のアプリケーション ドメインにディスパッチします。そのアプリケーション ドメインで、メッセージはマーシャリング解除され、リモート オブジェクト自身に対する呼び出しが行われます。
リモート処理がクライアントのドメインでリモート オブジェクトに対するプロキシを初期化すると、選択したチャネル上で IChannelSender.CreateMessageSink を呼び出すことにより、そのリモート オブジェクトと通信できるメッセージ シンクがクライアントによって構成されたチャネルから取得されます。
リモート処理システムのわかりにくい面の 1 つに、リモート オブジェクトとチャネルの関係があります。たとえば、呼び出しが着信したときだけオブジェクトがアクティブ化される場合、WellKnownObjectMode.SingleCall リモート オブジェクトは接続するクライアントをどのようにしてリッスンするのでしょうか。
これが可能な理由の 1 つは、リモート オブジェクトがチャネルを共有していることです。つまり、リモート オブジェクトは専用のチャネルを持ちません。リモート オブジェクトをホストするサーバー アプリケーションは、公開するオブジェクトだけでなく、必要とするチャネルをリモート処理システムに登録する必要があります。チャネルは、登録されると、指定されたポートで自動的にクライアント要求のリッスンを開始します。同期呼び出しの場合、クライアントからの接続はメッセージ呼び出しの存続期間にわたって維持されます。各クライアント接続はそれ自身のスレッドで処理されるため、1 つのチャネルで複数のクライアントを同時に処理できます。
参照
関連項目
概念
チャネルの選択
シリアル化フォーマッタ
シンクとシンク チェーン