.Net Remoting は複数の接続を開くのか、それとも 1 つだけ開くのか? サーバーとクライアントがあるとしましょう。クライアントが複数の SingleCall オブジェクトを作成する場合。では、すべてのオブジェクトに対して新しい接続が存在するのでしょうか、それともすべてのオブジェクトに対して単一の接続が存在するのでしょうか?
どこにも答えが見つかりません。
.Net Remoting は複数の接続を開くのか、それとも 1 つだけ開くのか? サーバーとクライアントがあるとしましょう。クライアントが複数の SingleCall オブジェクトを作成する場合。では、すべてのオブジェクトに対して新しい接続が存在するのでしょうか、それともすべてのオブジェクトに対して単一の接続が存在するのでしょうか?
どこにも答えが見つかりません。
長い答えは次のとおりです。それは多くのことに依存します。簡単な答えはイエスです。はいはい。
実験を行い、最も一般的なデフォルトの状況を見てみましょう。2 つのコンソール アプリと、両方のコンソール アプリによって参照される 1 つの共通クラス ライブラリがあります。1 つ目のコンソール アプリにはクライアントの役割があり、2 つ目のコンソール アプリにはサーバーの役割があります。
まず、一般的に依存するクラス ライブラリに含まれるものは次のとおりです。
public interface IFactory {
string Hello(string name);
}
次に、いくつかのサーバー コードについて説明します。起動は次のとおりです。
private static TcpChannel channel;
static void Main(string[] args) {
BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel = TypeFilterLevel.Full;
channel = new TcpChannel(
properties: new Hashtable {
{ @"port", 2013 }
},
clientSinkProvider: clientProv,
serverSinkProvider: serverProv
);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);
Console.WriteLine("Server started...");
Console.WriteLine("Press any key to stop...");
Console.ReadKey(intercept: true);
}
Factoryというクラスについて言及しました。
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);
当たってるよ。それはIFactoryの実装です:
private sealed class Factory : MarshalByRefObject, IFactory {
#region IFactory Members
string IFactory.Hello(string name) {
return @"Hello " + name + @" !";
}
#endregion
}
今、いくつかのクライアントのために:
static void Main(string[] args) {
Console.WriteLine("Press any key to connect...");
Console.ReadKey(intercept: true);
IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;
EventWaitHandle signal = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset);
ThreadStart action = () => {
signal.WaitOne();
var result = factory.Hello("Eduard");
Console.WriteLine(result);
};
foreach (var i in Enumerable.Range(0, 99))
new Thread(action) { IsBackground = true }.Start();
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);
signal.Set();
Console.ReadKey(intercept: true);
}
あなたはすでにこれらのことをすべて知っていると思います。反対側の SingleCall サービスへの透過プロキシを取得します (両方とも同じマシン上にあり、TCP ポート 2013 を使用しています)。
IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;
次に、「同時性」の理由から、100 個のスレッドを作成し、それらを開始します (これには時間がかかる場合があります)。引き金":
EventWaitHandle signal = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset);
ThreadStart action = () => {
signal.WaitOne();
var result = factory.Hello("Eduard");
Console.WriteLine(result);
};
foreach (var i in Enumerable.Range(0, 99))
new Thread(action) { IsBackground = true }.Start();
したがって、100 個のスレッドすべてが作成されて開始されていますが、それらはすべて次の呼び出しで待機しています。
signal.WaitOne();
そうしないと、スレッド自体の作成と開始により、実際の実行が多かれ少なかれシーケンシャルになります。
100 回の Hello 呼び出しで「サーバーを攻撃する」タイミングをユーザーに決定してもらいます。
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);
signal.Set();
そして、これが起こることです:
1)サーバーコンソール アプリを起動し、平和に実行します。
2)クライアントコンソール アプリを起動し、任意のキーを押して "接続を確立" します (透過プロキシを作成するだけなので、これは論理接続にすぎません) が、"砲撃" は延期します。
3) Mark Russinovich のProcess Explorerを起動し、それを使用してプロセス リストでクライアントプロセスを検出します。その間に、そのプロパティ ウィンドウを開き、[TCP/IP] タブを選択します。
4)クライアントコンソール アプリで任意のキーを押すと、.. TA DAA !! Process Explorerで多くの接続を 取得します。彼らは百ですか?はいの場合もあれば、いいえの場合もあります。それは確かに接続プールです。アイドル状態の短い時間 (5 ~ 10 秒) の後、それらは閉じます。これは非常に良いことです (.NET Remoting スタックがそのように実装されているため)。
この実験が一般的にあなたの質問に答えてくれることを願っています。
より具体的なケースで、より厳密な意味で、ドキュメントをチェックアウトし、.NET Remoting アプリで使用する可能性のあるさまざまなチャネルについて読む必要があります (そこにはたくさんのチャネルがあります。ここで見たのは、 Microsoft が公式に提供する通常の TcpChannel は、.NET Remoting 構成の内容、IIS でサーバーをホストしているかどうかなどによって異なります)。
ネットワーク接続の数は、使用するリモート チャネルによって異なります。デフォルトの TcpChannel は、プログラム内の多くのスレッドがある時点でサーバーにアクセスしようとするのと同じ数のネットワーク接続を開きます。
シングルスレッド アプリケーションの場合、TcpChannel は 1 つのネットワーク接続を使用します。
反対の例として、サード パーティのリモート チャネルIiopChannelは多重化を使用するため、何百ものアクティブ スレッドに対して少数のネットワーク接続のみを使用できます。