Przetwarzanie rozproszone Domeny Aplikacji ( AppDomain ) AppDomain A AppDomain B Pakiet A1 Pakiet B1 . . Pakiet Bm Pakiet An
tworzenie nowej domeny aplikacji // Ustawienie ApplicationBase na bieżący katalog AppDomainSetup info = new AppDomainSetup(); info.ApplicationBase = @"file:\\" + System.Environment.CurrentDirectory; // Utworzenie domeny aplikacji AppDomain dom = AppDomain.CreateDomain("RemoteDomain", null, info);
// Załadowanie pakietu Display // i utworzenie egzemplarza typu Display BindingFlags flags = (BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance); ObjectHandle objh = dom.CreateInstance ("Display", "Display.Disp", // plik, klasa false, flags, null, null, null, null, null); // Rozpakowanie obiektu Object obj = objh.Unwrap(); // Rzutowanie do aktualnego typu Disp h = (Disp)obj; // Wywołanie metody h.Show("Dobry wieczór!"); Domain
AppDomain A AppDomain B Wątek AP1 Wątek AP2 Wątek BP1 Aplikacja rozproszona AppDomain A AppDomain B Dane wspólne Dane wspólne Wątek AP1 Stos lokalny Pamięć lokalna Wątek AP2 Stos lokalny Pamięć lokalna Wątek BP1 Stos lokalny Pamięć lokalna
WCF Windows Communication Foundation Technologie wymiany danych pomiędzy aplikacjami IPC ( Inter Process Communication, Named Pipes ) DCOM, COM+ ( Distributed Common Object Model ) MSMQ ( Microsoft Message Queuing ) NET . Remoting XML Web Services NET.Networking (gniazda, klasy: transportowe, protokółów) Peer – to – Peer WCF Windows Communication Foundation
W C F : Windows Communication Foundation udostępnianie usług (operacji), kolekcji danych, komputer lokalny, sieć lokalna, internet zarządzanie usługodawcą: system Windows IIS : Internet Information Services WAS : Windows Activation Service (Win 7, WS) AppFabric (Windows Server) Juval Löwy, Programowanie usług WCF, Helion – O'Reilly, 2012
Przeźroczysty zastępca SingleCall, Singleton, ClientActivated NET . Remoting Obiekt zdalny Klient F1(x) F1(x) Przeźroczysty zastępca Serwer Rzeczywisty zastępca Kanał : HTTP, TCP { BIN, SOAP } pliki konfiguracyjne, konfiguracja programowa
W C F : Windows Communication Foundation Klient (client) Nosiciel (host) Zastępca (proxy) Kontrakt (contract) Plik konfiguracyjny (configuration file) Plik konfiguracyjny (configuration file)
ABC technologii WCF A : adres ( address ) - lokalizacja usługi, kolekcji danych B : powiązanie ( binding ) - protokóły, kodowanie, transport C : kontrakt ( contract ) - definicje udostępnianych metod, kolekcji danych A + B + C punkt końcowy ( endpoint )
Adresy ( lokalizacja kontraktu ) składnia adresu [ adres_bazowy ] / [ opcjonalny URI ] adres bazowy [ rodzaj_transportu ] [ komputer lub domena ] [ : opcjonalny numer portu ]
Rodzaje adresów adresy TCP net.tcp//localhost:8004/NowaUsługa net.tcp//150.254.3.2:7000/DalekaUsługa adresy HTTP http://localhost // port domyślny 80 http://libra:500/Matematyka adresy IPC net.pipe://localhost/DużaRura adresy MSMQ net.msmq://localhost/Kol_A // publiczna net.msmq://localhost/private/Kol_B // prywatna
Powiązania ( protokół transportowy / kodowanie ) powiązanie podstawowe ( interoperacyjne ) HTTP, HTTPS / tekstowe, MTOM ( SOAP Message Transmission Optimization Mechanism ) basicHttpBinding powiązanie TCP ( intranet, tylko WCF ) TCP / binarne ( Microsoft specific ) netTcpBinding
powiązanie IPC ( ten sam komputer ) IPC / binarne ( Microsoft specific ) netNamedPipeBinding powiązanie WS ( interoperacyjne WS-*) HTTP, HTTPS / tekstowe, MTOM wsHttpBinding powiązanie MSMQ MSMQ / binarne ( Microsoft specific ) netMsmqBinding
Rodzaje kontraktów kontrakt danych kontrakt komunikatów kontrakt usług kontrakt danych kontrakt komunikatów kontrakt błędów
Kontrakt usług interfejsy realizowane przez dedykowane klasy biblioteka .dll udostępniająca : interfejsy realizowane przez dedykowane klasy metody definiowane w klasach
// kontrakt - udostępnianie interfejsu using System.ServiceModel; namespace Wyrocznia { [ServiceContract] // ew. nazwa usługi, domena public interface IPorada [OperationContract] string Odpowiedz (string pytanie); } public class Babka : IPorada { public string Odpowiedz (string pytanie) { return " Tak! "; } } } // .dll
// udostępnianie metod [ServiceContract] public class WhereWhen { [OperationContract] public string Where ( ) { return " Miami "; } public string When ( ) { return " Tomorrow "; } }
using System.ServiceModel; // nosiciel using Wyrocznia; // .dll w katalogu domyślnym namespace NosicielWyroczni { class Nosiciel static void Main(string [ ] args) { using (ServiceHost sHost = new ServiceHost ( typeof ( Babka ))) { sHost.Open(); Console.WriteLine("Nosiciel jest czynny."); Console.WriteLine("Naciśnij Enter aby zakończyć..."); Console.ReadLine( ); } } } // aplikacja konsolowa
// klient // uruchomić nosiciela // AddServiceReference Wróżka, PoradaClient ( usługa, obiekt interfejsu ) // dodać referencję usługi Wróżka using KlientWyroczni.Wróżka; namespace KlientWyroczni { class Program { static void Main ( string [ ] args ) { using ( PoradaClient babka = new PoradaClient ( )) string odp = babka.Odpowiedz ( " Jak żyć ? " ); Console.WriteLine( "Wyrocznia powiedziała : " + odp ); } } } // można użyć svcutil.exe (NET.SDK)
Plik konfiguracyjny nosiciela <?xml version="1.0"?> <configuration> <system.serviceModel> <services> <service name="Wyrocznia.Babka" behaviorConfiguration="WyroczniaMEXBehavior"> <endpoint address="" binding="basicHttpBinding" contract="Wyrocznia.IPorada"/> <!-- Enable the MEX endpoint --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!-- Add this so MEX knows the address of service --> <host> <baseAddresses> <add baseAddress="http://localhost:8090/Babka"/> </baseAddresses> </host> </service></services> <!-- A behavior definition for MEX --> <behaviors> <serviceBehaviors> <behavior name="WyroczniaMEXBehavior"> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors></behaviors></system.serviceModel> </configuration> Wyrocznia HTTP
Powiązanie TCP Wyrocznia TCP // plik konfiguracyjny nosiciela <service name="Wyrocznia.Babka" behaviorConfiguration="WyroczniaMEXBehavior"> <endpoint address="" binding="netTcpBinding" contract="Wyrocznia.IPorada"/> <!-- Enable the MEX endpoint --> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8090/Babka"/> <add baseAddress="http://localhost:8080/Babka"/> </baseAddresses> </host> </service> Wyrocznia TCP
Powiązanie IPC Wyrocznia IPC // plik konfiguracyjny nosiciela <service name="Wyrocznia.Babka" behaviorConfiguration="WyroczniaMEXBehavior"> <endpoint address="" binding="netNamedPipeBinding" contract="Wyrocznia.IPorada"/> <!-- Enable the MEX endpoint --> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="net.pipe://localhost"/> <add baseAddress="http://localhost:8080/Babka"/> </baseAddresses> </host> </service> Wyrocznia IPC
Asynchroniczne wywołanie usługi kontrakt usługi, nosiciel : bez zmian uruchomić nosiciela po dokonaniu połączenia z nosicielem w oknie AddService Reference wybrać Advanced i zaznaczyć Generate asynchronous operations w programie klienta:
Wyrocznia ASY using (PoradaClient proxy = new PoradaClient()) { proxy.Open(); IAsyncResult result = proxy.BeginOdpowiedz( pytanie, // argument funkcji Odpowiedz // funkcja zwrotna ar => { Console.WriteLine("Wróżka odpowiedziała : " + proxy.EndOdpowiedz(ar)); }, null); // asyncState while (!result.IsCompleted) Thread.Sleep(100); } Wyrocznia ASY
// w programie usługi .dll Kontrakty danych // w programie usługi .dll [ServiceContract] public interface IUniversity { [OperationContract] Student GetStudent ( int album ); }
[DataContract] public class Student { [DataMember] public string ForeName; public string LastName; public int Album; public double Score; }
DataContract // nosiciel bez zmian ( .cs i .config ) // // klient dodawanie referencji serwisu bez zmian // program : using UnivClient.University; UniversityClient szukacz = new UniversityClient(); string pytanie; UnivClient.University.Student st; pytanie = Console.ReadLine(); st = szukacz.GetStudent( int.Parse ( pyt )); DataContract
ABC definiowane programowo kontrakt .dll bez zmian nosiciel using System.ServiceModel; using Wyrocznia; namespace Nosiciel { class Program { static void Main(string[] args) { ServiceHost serviceHost = new ServiceHost(typeof(Babka)); BasicHttpBinding basicBinding = new BasicHttpBinding(); serviceHost.AddServiceEndpoint(typeof(IPorada), basicBinding, "http://localhost:8091/Babka"); serviceHost.Open(); }}}
klient Prog // AddServiceReference jak poprzednio using System.ServiceModel; using Klient.Wróżka; namespace Klient { class Program { static void Main(string[] args) { BasicHttpBinding basicBinding = new BasicHttpBinding(); EndpointAddress address = new EndpointAddress("http://localhost:8091/Babka"); PoradaClient pytia = new PoradaClient(basicBinding, address); ...... } } } Prog
Usługi współużytkowane kontrakt .dll namespace Liczarka { [ServiceContract] public interface IDodawanie [OperationContract] int Dodaj(int start); }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class Licznik : IDodawanie { static int Obiekty = 0; int Ile = 0; public Licznik() { ++Obiekty; } public int Dodaj(int kto) return kto + ++Ile * 10 + Obiekty * 1000; }}
nosiciel static void Main(string[] args) { Console.WriteLine("***** Nosiciel Single *****"); Licznik lili = new Licznik(); ServiceHost serviceHost = new ServiceHost(lili); // Open the host and start listening. serviceHost.Open(); }
klient Single DodawanieClient licz = new DodawanieClient(); int odp, start = 3; Console.WriteLine("Dodaj 1 ... "); Console.ReadLine(); odp = licz.Dodaj(kto); Console.WriteLine("Kto = {0}, Licznik = {1}, Obiekty = {2}", (odp % 10).ToString(), (odp % 1000 / 10).ToString(), (odp / 1000).ToString() ); Single
Wydajność kanałów
TimePerf