简体   繁体   English

.Net Remoting只使用一个连接?

[英].Net Remoting uses only one connection ?

Does .Net Remoting opens multiple connections or just one ? .Net Remoting是打开多个连接还是只打开一个连接? let say I have a server and a client. 假设我有一台服务器和一台客户端。 if the client creates multiple SingleCall objects. 如果客户端创建多个SingleCall对象。 then for every object is there going to be a new connection or there going to be a single connection for every object ? 那么对于每个对象,是否会有一个新的连接,或者每个对象都会有一个连接?

I can't find the answer anywhere. 我无法在任何地方找到答案。

Long answer is: it depends on many things. 答案很长:这取决于很多事情。 Short answer is yes. 简短的回答是肯定的。 Yes Yes. 是的是的。

Let's make an experiment and see the most common default situation. 让我们做一个实验,看看最常见的默认情况。 We have 2 console apps and 1 common class library which is referred by both console apps. 我们有2个控制台应用程序和1个通用类库,由两个控制台应用程序引用。 The 1st console app has the role of the client and the 2nd one has that of the server. 第一个控制台应用程序具有客户端的角色,第二个控制台应用程序具有服务器的角色。

First, here's what the commonly depended upon class library contains: 首先,这是通常依赖于类库的内容:

public interface IFactory {

    string Hello(string name);

}

Now for some server code. 现在为一些服务器代码。 Here's the start up: 这是启动:

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);

}

We just mentioned a class called Factory . 我们刚才提到了一个名为Factory的类。

RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);

You guessed it. 你猜到了。 It's the IFactory implementation: 这是IFactory的实现:

private sealed class Factory : MarshalByRefObject, IFactory {

  #region IFactory Members

  string IFactory.Hello(string name) {
    return @"Hello " + name + @" !";
  }

  #endregion

}

Now for some client: 现在为一些客户:

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);
}

You already know all of these things, I'm sure. 你已经知道所有这些事情了,我敢肯定。 We obtain a transparent proxy to the SingleCall service on the other side (they're both on the same machine and we're using TCP port 2013): 我们在另一侧获得了SingleCall服务的透明代理(它们都在同一台机器上,我们使用的是TCP端口2013):

IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;

Then, for "simulataneous-ness" reasons we create 100 threads, start them (which can take some time), but "hold them in a leash" (a signal is an essential means of synchronization of the OS) until we "pull the trigger": 然后,出于“同时性”的原因,我们创建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();

So although all 100 threads have been created AND started, they are all waiting in the following invocation: 因此,虽然已经创建启动了所有100个线程,但它们都在以下调用中等待:

signal.WaitOne();

That way we can get the to start at the same time better , otherwise the creation and starting of threads itself would have made their actual execution more or less sequential. 这样我们可以更好地同时启动,否则线程本身的创建和启动会使其实际执行或多或少地顺序执行。

We ask the user to decide when to "bombard the server" with 100 Hello invocations: 我们要求用户决定何时使用100个Hello调用“轰炸服务器”:

Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);

signal.Set();

And this is what happens: 这就是发生的事情:

1) We start the server console app and let it run in peace: 1)我们启动服务器控制台应用程序,让它运行平安:

在此输入图像描述

2) We start the client console app, "make the connection" by pressing any key (which is only a logical connection since it just creates a transparent proxy) but we postpone the "bombardment": 2)我们启动客户端控制台应用程序,通过按任意键“进行连接”(这只是一个逻辑连接,因为它只是创建一个透明代理)但我们推迟了“轰炸”:

在此输入图像描述

3) We start up Mark Russinovich's Process Explorer and use it to discover the client process in the process list, and while doing that we open it's properties window and select the TCP/IP tab: 3)我们启动Mark Russinovich的Process Explorer并使用它来发现进程列表中的客户端进程,并在执行此操作时打开它的属性窗口并选择TCP / IP选项卡:

在此输入图像描述

4) We hit any key in the client console app, and .. TA DAA !! 4)我们点击客户端控制台应用程序中的任何键,然后.. TA DAA !! You get a lot of connections in Process Explorer . 您在Process Explorer中获得了大量连接。 Are they a hundred ? 他们是百? Sometimes yes, sometimes no. 有时是,有时没有。 It's a connection pool, that's for sure. 这是一个连接池,这是肯定的。 After a short while (5 to 10 seconds) of idleness they close down which is a very good thing (because the .NET Remoting stack is implemented that way). 在短暂停留(5到10秒)之后,它们关闭了,这是一件非常好的事情(因为.NET Remoting堆栈是以这种方式实现的)。

在此输入图像描述

I hope this experiment generally answered your question. 我希望这个实验能够回答你的问题。

In more specific cases and in a more rigorous sense you should check out the documentation and read about the various channels that you might use in your .NET Remoting apps (there are loads of them out there, what you've seen here is just the regular TcpChannel officially provided by Microsoft, it depends on what your .NET Remoting configuration says, on whether you're hosting the server in IIS or not, etc). 在更具体的情况下,在更严格的意义上,您应该查看文档并阅读您可能在.NET Remoting应用程序中使用的各种渠道(其中有很多,你在这里看到的只是由Microsoft正式提供的常规TcpChannel,它取决于您的.NET Remoting配置所说的内容,关于您是否在IIS中托管服务器等)。

The number of network connections depends on remoting channel you use. 网络连接数取决于您使用的远程通道。 The default TcpChannel opens as many network connections as many threads in your program try to access the server during one point of time. 默认的TcpChannel打开尽可能多的网络连接,因为程序中的许多线程会尝试在一个时间点访问服务器。

For single-threaded applications, TcpChannel uses one network connection. 对于单线程应用程序,TcpChannel使用一个网络连接。

As an opposite example, a third party remoting channel IiopChannel uses multiplexing and thus allows to have just a few network connections for many hundreds of active threads. 作为相反的示例,第三方远程通道IiopChannel使用多路复用,因此允许仅有几个网络连接用于数百个活动线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM