Michał Jankowski Remoting w.net 2.0
Co to jest? Remoting jest zbiorem funkcji pozwalającym na komunikacje miedzy aplikacjami zarówno w obrębie jednego komputera jak i poprzez sieć Pozwala na komunikację za pomocą różnych sposobów Następna technologii DCOM Odpowiednik RMI z Java lub systemu przetwarzania rozproszonego COBRA
Przesyłanie wyników Przez referencje (ang. Marshal by reference - MBR) obiekty istnieją jedynie na serwerze i tylko tam wykonywane są wszystkie metody danej klasy. Podczas komunikacji przekazywana jest jedynie referencja do obiektu, a nie obiekt. Powoduje to, że klient nie zna implementacji metod serwera, a jedynie może uzyskać wynik jej wywołania. W celu skorzystania z tej opcji nasza klasa musi dziedziczyć z klasy MarshalByRefObject. Przez wartość (ang. Marshal by value MBV), klient posiada pełną informację na temat obiektu. Dodatkowo w tym przypadku musimy zapewnić możliwość zdalnego przekazywania obiektu przez medium komunikacyjne przedstawić obiekt zdalny do serializacji. W tym celu przed definicją klasy obiektu wstawiamy atrybut [Serializable]. Obiekt po przesłaniu jest wykorzystywany w kontekście lokalnym.
Typy obiektów ServerActivatedObjects SOA obiekty aktywowane przez serwer: SingleCall dla każdego wywołania metody na serwerze tworzona jest instancja klasy zdalnej, która istnieje tylko w czasie działania metody, a po jej zakończeniu jest niszczona (nie może przechowywać stanu, ale zapewnia łatwą skalowalność) Singleton dla każdej wywołanej metody serwer sprawdza czy istnieje już obiekt tej klasy i jeśli tak to korzysta z niego, a jeśli nie to go tworzy, a następnie wywołuje metodę na rzecz tego obiektu. Powoduje to, że serwer może przechować stan tego obiektu, a co za tym idzie obsłużyć kilku klientów w tym samym kontekście. ClientActivatedObjects COA obiekty aktywowane przez klienta.
Jak z tego korzystać klasa usługowa class Oblicz : MarshalByRefObject { } //Dodawanie dwoch liczb public double Dodaj( double a, double b) { return a + b; } //Odejmowanie liczby b od a public double Odejmij( double a, double b) { return a - b; } //Mnożenie dwóch liczb public double Mnoz( double a, double b) { return a * b; } //Dzielenie liczby a przez b, pomijam wyjątek dzielenia przez 0 public double Dziel( double a, double b) { return a / b; }
Serwer - konfiguracja <? xml version = " 1.0 " encoding = " utf-8 "?> < configuration > < system.runtime.remoting > < application > < channels > < channel ref = " http " port = " 5000 " /> </ channels > < service > < wellknown mode = " SingleCall " type = " Serwer.Oblicz,Serwer " objecturi = " Kalkulator " /> </ service > </ application > </ system.runtime.remoting > </ configuration >
Serwer - kod class ObliczSerwer { public static void Main() { //Konfiguruje serwer System.Runtime.Remoting.RemotingConfiguration.Configure(AppDoma in.currentdomain.setupinformation.configurationfile, false); //Czeka na naciśnięcie przycisku Console.WriteLine("Nacisnij przycisk w celu zakonczenia aplikacji"); Console.ReadLine(); } }
Klient poznajemy obiekt public interface IOblicz { double Dodaj(double a, double b); double Odejmij(double a, double b); double Mnoz(double a, double b); double Dziel(double a, double b); }
Klient komunikacja z serwerem using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; class ObliczKlient { } public static void Main() { //Definicja kanału HttpChannel chan = new HttpChannel(); //Rejestracja kanału ChannelServices.RegisterChannel(chan, false); //Tworzenie klasy pośredniczącej dla zdalnego obiektu IOblicz kalkulator = (IOblicz) Activator.GetObject(typeof(IOblicz), "http://localhost:5000/kalkulator"); Console.WriteLine("3.5*2.1="+kalkulator.Mnoz(3.5, 2.1)); }
Binarne przesyłanie danych < clientproviders > < formatter ref = " binary " /> </ clientproviders > //Definicja formatera BinaryClientFormatterSinkProvider formatter = new BinaryClientFormatterSinkProvider (); //Definicja kanału HttpChannel chan = new HttpChannel ( null, formatter, null ); //Rejestracja kanału ChannelServices.RegisterChannel(chan, false );
Zmiana protokłu < channels > < channel ref = " tcp " port = " 5000 " /> </ channels > TcpChannel chan = new TcpChannel(); ChannelServices.RegisterChannel(chan, false); ComplexNumber cn = new ComplexNumber(1.1,2.2); IComplexNumbersCalculator calculator = (IComplexNumbersCalculator) Activator.GetObject(typeof(IComplexNumbersCalculator), "tcp://localhost:801/complexnumberscalculator");
Szyfrowanie < channel ref = " tcp " port = " 5000 " secure = " true " protectionlevel = " EncryptAndSign " /> None występuje tylko uwierzytelnianie (Win 95 / 98 / ME) Sign dane są podpisywane, w celu zapewnienia spójności danych EncryptAndSign dane są kodowane i podpisywane w celu zapewnienia poufności i spójności danych. ChannelServices.RegisterChannel(chan, true );
Dziękuję za uwagę