2013-02-21 86 views
5

Czy .Net Remoting otwiera wiele połączeń lub tylko jedno? Powiedzmy, że mam serwer i klienta. jeśli klient tworzy wiele obiektów SingleCall. to czy dla każdego obiektu będzie nowe połączenie, czy też dla każdego obiektu będzie jedno połączenie?.Net Remoting używa tylko jednego połączenia?

Nie mogę znaleźć odpowiedzi w dowolnym miejscu.

+2

Myślę, że to zależy od tego, z jakiego kanału (kanałów) są używane, ale * dlaczego * piszesz remoting code w 2013? –

+0

@Damien_The_Unbeliever może pracował nad starym projektem. co masz na myśli, że zależy to od kanału? kanały to określają? – m1o2

Odpowiedz

0

Liczba połączeń sieciowych zależy od używanego kanału zdalnego dostępu. Domyślny TcpChannel otwiera tyle połączeń sieciowych, ile wątków w twoim programie próbuje uzyskać dostęp do serwera w jednym momencie.

W przypadku aplikacji jednowątkowych TcpChannel wykorzystuje jedno połączenie sieciowe.

Jako odwrotny przykład, zewnętrzny kanał zdalny IiopChannel wykorzystuje multipleksowanie, a tym samym pozwala mieć tylko kilka połączeń sieciowych dla wielu setek aktywnych wątków.

7

Długa odpowiedź brzmi: zależy to od wielu rzeczy. Krótka odpowiedź brzmi: tak. Tak tak.

Zróbmy eksperyment i zobaczmy najczęstszą sytuację domyślną. Mamy dwie aplikacje konsolowe i jedną wspólną bibliotekę klas, która jest polecana przez obie aplikacje konsolowe. Pierwsza aplikacja konsolowa pełni rolę klienta, a druga ma rolę serwera.

pierwsze, oto co powszechnie zależało biblioteka klasa zawiera:

public interface IFactory { 

    string Hello(string name); 

} 

Teraz jakiegoś kodu serwera. Oto uruchomić:

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

} 

Właśnie wymienione klasy o nazwie Fabryka.

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

Zgadłeś. To IFactory realizacja:

private sealed class Factory : MarshalByRefObject, IFactory { 

    #region IFactory Members 

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

    #endregion 

} 

Teraz jakiegoś klienta:

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

Wiesz już wszystko z tych rzeczy, jestem pewien. Otrzymujemy przezroczyste proxy do usługi SingleCall po drugiej stronie (obaj są na tym samym komputerze, a my za pomocą portu TCP 2013):

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

Następnie dla „symultaniczne-Ness” powodów tworzymy 100 wątków, zacznij je (co może zająć trochę czasu), ale „trzymać je na smyczy” (sygnał jest podstawowym środkiem synchronizacji OS), dopóki nie „ciągnąć za spust”:

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

Tak chociaż wszystkie 100 wątków zostały utworzone i rozpoczęte, wszystkie czekają w następującej inwokacji:

signal.WaitOne(); 

W ten sposób możemy uzyskać, aby rozpocząć w tym samym czasie lepiej, w przeciwnym wypadku stworzenie i uruchomienie wątków będzie sama dokonały ich faktyczne wykonanie bardziej lub mniej sekwencyjną.

Pytamy użytkownikowi zdecydować, kiedy „bombardować serwer” 100 Witam inwokacji:

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

signal.Set(); 

i to, co się dzieje:

1) Zaczynamy aplikację konsoli serwera i uruchomić ją w spokoju:

enter image description here

2) Rozpoczynamy klient app konsoli „nawiązać połączenie” przez naciśnięcie dowolnego klawisza (który jest tylko połączenie logiczne, ponieważ to właśnie tworzy przezroczyste proxy), ale odroczyć „bombardowanie”:

enter image description here

3) My uruchomić Mark Russinovichem na Process Explorer i użyć go do odkryć klienta proces w liście procesów, a robiąc to możemy otworzyć to okno właściwości i wybrać zakładkę TCP/IP:

enter image description here

4) Udało nam się trafić dowolny klucz w aplikacji klienta i .. TA DAA !! Otrzymujesz dużo połączeń w Process Explorer. Czy oni sto? Czasem tak, czasem nie. To jest pula połączeń, to na pewno. Po krótkiej chwili (5 do 10 sekund) bezczynności zostają one zamknięte, co jest bardzo dobrą rzeczą (ponieważ stos .NET Remoting jest zaimplementowany w ten sposób).

enter image description here

Mam nadzieję, że ten eksperyment ogólnie odpowiedział na to pytanie.

W bardziej konkretnych przypadkach iw bardziej rygorystycznym sensie powinieneś zapoznać się z dokumentacją i przeczytać o różnych kanałach, które możesz wykorzystać w swoich aplikacjach .NET Remoting (jest ich mnóstwo, co widziałeś tutaj jest tylko zwykły TcpChannel oficjalnie dostarczony przez Microsoft, to zależy od tego, co mówi konfiguracja .NET Remoting, od tego, czy hostujesz serwer w IIS, czy nie, itd.).

+0

to jest absolutnie piękna odpowiedź. Dziękuję Ci! – Quibblesome