• Nie Znaleziono Wyników

Laboratorium 3

N/A
N/A
Protected

Academic year: 2021

Share "Laboratorium 3"

Copied!
13
0
0

Pełen tekst

(1)

Programowanie Systemów Rozproszonych

Laboratorium 3

WCF

Paweł Paduch

paduch@tu.kielce.pl

12-04-2016

(2)

Rozdział 1

Wstęp

1.1

Materiały pomocniczne

Do zajęć przydatne mogą być:

• materiały udostępniane przez prowadzących wykłady

• książki związane z tematyką programowania np. „Język C# 2010 i

plat-forma .NET“Andrew Troelsena

• książki związane z tematyką programowania współbieżnego np.

„Progra-mowanie równoległe i asynchroniczne w C# 5.0”

• kursy i poradniki w sieci np. http://www.centrumxp.pl/

• Tutoriale Microsoftu np.https://msdn.microsoft.com/en-us/library/ms731064(v=vs.110).aspx

(3)

Rozdział 2

Komunikacja

dwukierunkowa - kontrakty

Po zalogowaniu się z menu start odnajdujemy program Microsoft Visual

Stu-dio 2010, lub nowszy.

2.1

Service Contract

Z górnego menu wybieramy: File-> New Project. W okienku jak na rysunku

Rysunek 2.1: Okienko wybierania nowego projektu

2.1zaznaczamy Visual C#->Windows WCF Service Library. Na dole wpisujemy

nazwę projektu DuplexServiceLibrary i nazwę solucji Lab3, potwierdzamy OK. Powinny powstać nam 3 pliki:

(4)

• Service.cs • App.config

Zmieniamy nazwę IService1.cs na IDuplexCalc.cs. W interfejsie definiujemy jakie operacje będzie udostępniać nasz serwis, (dodawanie, odejmowanie, mno-żenie, dzielenie) ale też definiujemy jakie operacje może wywoływac u klienta. Będą to odpowiednio Wyświetlenie wyniku i wyświetlenie równania.

Listing 2.1: IDuplexCalc.cs 1 usingSystem; 2 usingSystem.Collections.Generic; 3 usingSystem.Linq; 4 usingSystem.Runtime.Serialization; 5 usingSystem.ServiceModel; 6 usingSystem.Text; 7 8 namespaceDuplexServiceLibrary 9 { 10 [ServiceContract(SessionMode = SessionMode.Required, 11 CallbackContract = typeof(IDuplexCalcCallback))] 12 public interfaceIDuplexCalc {

13 [OperationContract(IsOneWay = true)] 14 void Wyczysc();

15 [OperationContract(IsOneWay = true)] 16 void DodajDo(double n);

17 [OperationContract(IsOneWay = true)] 18 void OdejmijOd(double n);

19 [OperationContract(IsOneWay = true)] 20 void PomnozPrzez(doublen); 21 [OperationContract(IsOneWay = true)] 22 void PodzielPrzez(double n); 23 }

24

25 public interfaceIDuplexCalcCallback 26 {

27 [OperationContract(IsOneWay = true)] 28 void Wynik(double result);

29 [OperationContract(IsOneWay = true)] 30 void Rownanie(string eqn);

31 } 32 }

2.2

Implementacja Kontraktu

Zmieniamy nazwę pliku Service1.cs na DuplexCalc.cs

Ustawiamy dziedziczenie DuplexCalc po IDuplexCalc. Można posłużyć się rozwi-janym menu by wygenerować automatycznie odpowiednie metody. Implemen-tujemy poszczególne metody jednocześnie implementując właściwość Calback zwracającą kanał zwrotny typu IDuplexCalcCallback

Listing 2.2: Zaimplementowane metody w DuplexCalc.cs

1 usingSystem; 2 usingSystem.Collections.Generic; 3 usingSystem.Linq; 4 usingSystem.Runtime.Serialization; 5 usingSystem.ServiceModel; 6 usingSystem.Text; 7 8 namespaceDuplexServiceLibrary

(5)

9 {

10 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,

←-ConcurrencyMode = ←-ConcurrencyMode.Single)]

11 public classDuplexCalc : IDuplexCalc 12 { 13 14 double wynik = 0.0D; 15 string rownanie; 16 17 public DuplexCalc() 18 { 19 rownanie = wynik.ToString(); 20 } 21

22 public void Wyczysc()

23 {

24 Callback.Rownanie(rownanie +" = " + wynik.ToString()); 25 rownanie = wynik.ToString();

26 }

27

28 public void DodajDo(double n)

29 { 30 wynik += n; 31 rownanie += " + "+ n.ToString(); 32 Callback.Wynik(wynik); 33 } 34

35 public void OdejmijOd(double n)

36 { 37 wynik -= n; 38 rownanie += " - "+ n.ToString(); 39 Callback.Wynik(wynik); 40 } 41

42 public void PomnozPrzez(double n)

43 { 44 wynik *= n; 45 rownanie += " * "+ n.ToString(); 46 Callback.Wynik(wynik); 47 } 48

49 public void PodzielPrzez(double n)

50 { 51 wynik /= n; 52 rownanie += " / "+ n.ToString(); 53 Callback.Wynik(wynik); 54 } 55 56 IDuplexCalcCallback Callback 57 { 58 get 59 { 60 return OperationContext.Current.GetCallbackChannel<←-IDuplexCalcCallback>(); 61 } 62 } 63 64 } 65 }

2.3

App.config

Należy, zmienić nazewnictwo w pliku App.config z Service1 na

DuplexCal-culator oraz IService1 na IDuplexCalc. Zmienić też typ bindingu z BasicHttp-Binding na wsDualHttpBinding. Dodać sekcje bindings z definicją

(6)

Listing 2.3: App.config

1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration>

3

4 <system.web>

5 <compilation debug="true" /> 6 </system.web>

7 <!-- When deploying the service library project, the content of the config file

←-must be added to the host's

8 app.config file. System.Configuration does not support config files for libraries.

←--->

9 <system.serviceModel> 10 <services>

11 <service name="DuplexServiceLibrary.DuplexCalc">

12 <endpoint address="" binding="wsDualHttpBinding"

contract="←-DuplexServiceLibrary.IDuplexCalc" bindingConfiguration="DuplexBinding">

13 <identity>

14 <dns value="localhost" /> 15 </identity>

16 </endpoint>

17 <endpoint address="mex" binding="mexHttpBinding"

contract="IMetadataExchange"←-/> 18 <host> 19 <baseAddresses> 20 <add baseAddress="http://localhost:8733←-/Design_Time_Addresses/DuplexServiceLibrary/DuplexCalculator/" /> 21 </baseAddresses> 22 </host> 23 </service> 24 </services> 25 <bindings> 26 <wsDualHttpBinding>

27 <binding name="DuplexBinding"

clientBaseAddress="http://localhost:8000←-/DuplexCalc/"/> 28 </wsDualHttpBinding> 29 </bindings> 30 <behaviors> 31 <serviceBehaviors> 32 <behavior>

33 <!-- To avoid disclosing metadata information, 34 set the value below to false before deployment --> 35 <serviceMetadata httpGetEnabled="True"/>

36 <!-- To receive exception details in faults for debugging purposes, 37 set the value below to true. Set to false before deployment 38 to avoid disclosing exception information -->

39 <serviceDebug includeExceptionDetailInFaults="true" /> 40 </behavior> 41 </serviceBehaviors> 42 </behaviors> 43 </system.serviceModel> 44 45 </configuration>

2.4

Pierwsze uruchomienie

Już teraz można uruchomić nasz serwis wciskając F5. Serwis będzie hosto-wany w środowisku uruchomieniowym, włączony zostanie też prosty klient do

testowania rozwiązań (rys. 2.2).

2.5

Hostowanie serwisu

Stworzymy sobie prostą aplikację konsolową hostującą nasz serwis.

1. Dodaj do solucji nowy projekt typu Console Application i nazwij ją

(7)

Rysunek 2.2: WCF Test Client

2. We właściwościach projektu zmień Target framework na .NET Framework

4.5 (rys.2.3). Projekt zostanie przeładowany.

3. Dodaj referencję do DuplexServiceLibrary. W solution explorerze prawym klawiszem myszy na klikamy na References i wybieramy Add reference. Wybieramy z menu z lewej strony Solution -> Projects i zaznaczamy

Du-plexServiceLibrary(rys.2.4). Dzięki temu aplikacja będzie znała typy

uży-wane w projekcie serwisu.

4. Dodaj referencję do System.ServiceModel. Podobnie jak wyżej, tylko na-leży wybrać nie Solution a Assemblies->Framework i tam zaznaczyć

Sys-tem.ServiceModel.

Uzupełnij kod w pliku Program.cs jak na listingu2.4

Listing 2.4: Główny program hostujący serwis

1 usingSystem; 2 usingSystem.Collections.Generic; 3 usingSystem.Linq; 4 usingSystem.ServiceModel; 5 usingSystem.ServiceModel.Description; 6 usingSystem.Text; 7 usingDuplexServiceLibrary; 8 9 namespaceDuplexServiceHost 10 { 11 classProgram 12 {

13 static void Main(string[] args)

14 {

15 // Tworzymy adres pod którym będzie dostępna usługa

16 Uri baseAddress = new Uri("http://localhost:8001/DuplexCalcService/"); 17

18 // Tworzymy obiekt klasy DuplexCalc

19 ServiceHost selfHost = newServiceHost(typeof(DuplexCalc), baseAddress); 20

21 try

22 {

23 // Dodajemy Endopoint usługi 24

25 selfHost.AddServiceEndpoint(typeof(IDuplexCalc), new

(8)

Rysunek 2.3: Właściwości projektu

(9)

26

27 // Umożliwiamy wymianę metadanych

28 ServiceMetadataBehavior smb =newServiceMetadataBehavior(); 29 smb.HttpGetEnabled =true;

30 // Umożliwiamy przesłanie dodatkowych danych na temat wyjątku 31 selfHost.Description.Behaviors.Find<ServiceDebugBehavior>().←-IncludeExceptionDetailInFaults = true; 32 selfHost.Description.Behaviors.Add(smb); 33 34 35 // Startujemy serwis 36 selfHost.Open();

37 Console.WriteLine("Serwis działa....");

38 Console.WriteLine("Naciśnij <ENTER> by zakończyć."); 39 Console.WriteLine(); 40 Console.ReadLine(); 41 42 // zamykamy serwis 43 selfHost.Close(); 44 }

45 catch (CommunicationException ce)

46 {

47 Console.WriteLine("Przechwyciłem wyjątek: {0}", ce.Message); 48 selfHost.Abort();

49 }

50 }

51 } 52 }

W linii 25 tworzymy Endpoint serwisu. Jest on złożony z adresu, bindingu oraz kontraktów.

Kontrakt to IDuplexCalc. Binding to WSDualHttpBinding, który jest predefi-niowanym bindingiem, umożliwia on komunikację dwustronną. Od wersji .Net 4.0 podawanie bindingu nie jest wymagane. Zostanie on automatycznie wyge-nerowany dla wszystkich par bazowy adres i kontrakt.

W linii 28 umożliwiamy wymianę metadanych serwisu. Klienci używają meta-danych do wygenerowania proxy służących do komunikowania się z serwisem. Należy:

• stworzyć obiekt klasy ServiceMetadataBehavior • ustawić jego parametr HttpGetEnabled na true

• dodać „zachowanie” (behavior) do kolekcji System.ServiceModel.ServiceHost.Behaviors. W lini 31 umożliwiamy przesyłanie błędów z serwisu do klienta.

W linii 36 otwieramy host do nasłuchiwania przychodzących komunikatów. Ustawiamy projekt DuplexServiceHost jako StartUp Project i uruchamiamy.

Możemy uruchomić przeglądarkę i wejść na adres: http://localhost:8001/DuplexCalcService/. Powinniśmy zobaczyć linki do plików WSDL oraz przykład prostego klienta.

2.6

Klient

Klient korzysta z klas proxy wygenerowanych na podstawie metadanych. Metadane często są w postaci pliku WSDL (plik xmlowy opisujący web service). Klasy proxy można wygenerować za pomocą narzędzia Svcutil.exe dostępnego z konsoli Visual Studio Command Prompt lub z poziomu Visual Studio.

(10)
(11)

1. Dodaj nowy projekt typu aplikacja konsolowa o nazwie

DuplexCalcPro-gram do solucji Lab3.

2. Ustaw we właściwościach projektu Target Framework na .Net 4.5 3. Dodaj referencje do System.ServiceModel

4. Dodaj dodaj referencje do serwisu. W tym celu należy:

• Uruchomić program CalculatorHost tak by serwis działał i wystawił metadane na adresie http://localhost:8001/DuplexCalcService/. Na-leży uruchomić w trybie bez debugowania (ctrl+F5).

• Prawym klawiszem myszy kliknąć w solution explorerze na References w projekcie DuplexCalcProgram i wybrać Add Service Reference. • podać adres serwisu i nacisnąć guzik Go.

• po odkryciu naszego serwisu podajemy nazwę przestrzeni nazw

Du-plexCalcServiceRef (rys.2.6) i naciskamy OK.

Rysunek 2.6: Dodaj referencje do serwisu

• zostanie wygenerowany kod do klas proxy oraz plik konfiguracyjny

app.config.

5. Jeżeli chcielibyśmy użyc narzędzia Svcutil.exe należałoby podać mniej wię-cej taką komendę:

svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8001/DuplexCalcService/

(12)

6. W kodzie musimy stworzyć klasę implementującą wywołania serwisu na kliencie CallbackHandler. Są tam dwie metody Wynik i Rownanie. Serwis za każdym razem gdy wołamy metodę liczacą, wywołuje u klienta metodę zwracająca wynik.

7. Uzupełniamy kod programu o odpowiednią przestrzeń nazw oraz tworzy-my obiekt klasy DuplexCalcClient wołatworzy-my metody operujące na

kalkula-torze np DodajDo czy PomnozPrzez jak listeningu (2.5)

Listing 2.5: Calculator Client

1 usingSystem; 2 usingSystem.Collections.Generic; 3 usingSystem.Linq; 4 usingSystem.ServiceModel; 5 usingSystem.Text; 6 usingDuplexCalcProgram.DuplexCalcServiceRef; 7 8 namespaceDuplexCalcProgram 9 { 10

11 public classCallbackHandler : IDuplexCalcCallback 12 {

13 public void Wynik(double result)

14 {

15 Console.WriteLine("Wynik({0})", result);

16 }

17

18 public void Rownanie(string eqn)

19 {

20 Console.WriteLine("Równanie({0})", eqn);

21 }

22 }

23 classProgram 24 {

25 static void Main(string[] args)

26 {

27

28 InstanceContext instanceContext = newInstanceContext(new

CallbackHandler←-());

29

30 DuplexCalcClient client = newDuplexCalcClient(instanceContext); 31 client.Open(); 32 client.DodajDo(5.0); 33 client.DodajDo(3.0); 34 client.PomnozPrzez(2.0); 35 client.PodzielPrzez(4.0); 36 client.OdejmijOd(1); 37 client.Wyczysc(); 38 Console.ReadLine(); 39 40 client.Close(); 41 } 42 } 43 }

(13)

Rozdział 3

Zadania do samodzielnego

wykonania

Dodać do Callbacku wątek, który co sekundę woła metodę u klienta

(licznik-Stan), która przekaże mu stan licznika. Licznik powinien startować od pierwszej

operacji wykonanej na serwisie i zatrzymywać się za pomocą innej zdalnej me-tody np licznikStop.

Cytaty

Powiązane dokumenty

Na efektywnoúÊ wykorzystywania akwizycji w sektorze tzw. nowej ekonomii wp≥ywa wymagana szybkoúÊ rozwoju. PrzejÍcia dajπ zazwyczaj moøliwoúÊ szyb- szego wzrostu niø

Wprowadzamy nowe pojęcie „stopień ważności wyrobów&#34; (patrz tab. Dla każdego wyrobu podanego w tabeli zapotrzebowania okreś­ lamy stopień ważności x. Dobór

Jakkolw iek nie wolna od tego rodzaju dysproporcji, książka Olschowsky’ego reprezentuje sty l myślenia i sposób rozumienia literatury , któ ry — pow tórzm y —

„Makbet Lidii Zamkow przejdzie zapewne do historii teatru jako jedna z cie- kawszych propozycji inscenizacyjnych” – wyrażał nadzieję recenzent „Tygodnika Powszechnego”

A., &#34;Combination of Various Load Processes,&#34; Journal of the Structural Division, American Society Civil Engineers, Vol. 0., &#34;Load Combinations in Cod- ified

Zasadą było dokształcanie za granicą tych absolwentów, którzy, po odpo- wiednich egzaminach, zostali wytypowani na uzupełniające studia zagraniczne (np. wspomniany Pawłowicz).

Celem opracowania koncepcji ergonomicznego rekomendowania wyrobów, wykony- wanego przez grono ekspertów powołanych przez Polskie Towarzystwo Ergonomiczne (PTErg), jest

minimaliseren  van  energieverlies