Środowiska rozproszone WebService
Literatura Głównie informacje w sieci: www.wikipedia.pl www.w3.org www.google.pl http://www.cs.fsu.edu/~engelen/soap.html http://www.cs.fsu.edu/~engelen/calc.wsdl - przydkład serwisu 2
WebService Jest usługą sieciową, komponent programowy niezależny od platformy i implementacji, dostarczający określonej funkcjonalności. Na bazie usług sieciowych można konstruować rozproszone systemy i aplikacje Aplikacje komunikują się z usługami sieciowymi z wykorzystaniem internetowych protokołów i formatów danych, zwykle jest to SOAP zatwierdzony przez W3C Źródło: wikipedia 3
WebService SOAP ( Simple Object Access Protocol (SOAP)) - protokół wywoływania zdalnego dostępu do obiektów, wykorzystujący XML do kodowania wywołań i najczęściej HTTP do ich przenoszenia, możliwe jest jednak wykorzystanie innych protokołów do transportu danych Źródło: wikipedia 4
WebService Dokument SOAP składa się z trzech części: otoczki (envelope) która określa szkielet opisujący co znajduje się w komunikacie i jak go przetwarzać, zbioru reguł kodujących potrzebnych do rozszyfrowania typów danych (również złożonych) zdefiniowanych wewnątrz aplikacji, reguł dotyczących wywoływania zdalnych metod i odczytu odpowiedzi. Źródło: Wikipedia 5
WebService Implementacje SOAP to m.in.: Apache SOAP SOAP::Lite.NET gsoap Źródło: wikipedia 6
WebService - zaczynamy Bobieramy pakiet z http://sourceforge.net/projects/gsoap2 Rozpakowujemy np. do /usr/local/src/gsoap-2.7 W rozpakowanym katalogu wykonujemy./configure Make make install Wymaga openssl-devel 7
WebService - zaczynamy Lub instalując paczkę np: yum -y install gsoap-devel Źródło: wikipedia 8
WebService - zaczynamy Uwaga! Na niektórych systemach funkcje strtod_l i prawdopodobnie strtof_l działają niepoprawnie. Uruchomienie webserwisu z typami double i float powoduje segmentation fault. (plik stdsoap2.c chociażby) Rozwiązanie: oddefiniować HAVE_STRTOD_L oraz HAVE_STRTOF_L czyli w pliku configure.h w źródłach gsoapa zmienić linię: #define HAVE_STRTOD_L 1 na #undef HAVE_STRTOD_L oraz #define HAVE_STRTOF_L 1 na #undef HAVE_STRTOF_L następnie make clean; make; make install 9
WebService - zaczynamy Dostaniemy do dyspozycji Biblioteki do dolinkowania lgsoap++ dla programów c++ lgsoap dla programów w c lgsoapck++ wsparcie dla cookie w c++ lgsoapck wsparcie dla cookie w c Plik nagłówkowy stdsoap2.h Programy Wsdl2h soapcpp2 Źródło: wikipedia 10
WebService - zaczynamy Jak to działa przykład klienta: Źródło: http://www.cs.fsu.edu/~engelen/soap.html 11
WebService - zaczynamy Jak to działa przykład serwera: Źródło: http://www.cs.fsu.edu/~engelen/soap.html 12
Tworzymy pierwszy serwer WebService - zaczynamy // Contents of file "kalk_serv.h": //gsoap ns service style: rpc //gsoap ns service name: kalkulatorws //gsoap ns service namespace: urn:kalkulator //gsoap ns service port: http://localhost/cgi-bin/akalk.cgi typedef double xsd double; int ns dodaj( xsd double a, xsd double b, xsd double *result); int ns odejmij(xsd double a, xsd double b, xsd double *result); int ns mnoz(xsd double a, xsd double b, xsd double *result); int ns dziel(xsd double a, xsd double b, xsd double *result); int ns pierwiastek(xsd double a, xsd double *result); int ns potega(xsd double a, xsd double *result); soapcpp2 -S -c -e kalk_serv.h Powstaną nam pliki szkieletu programu. Oraz plik kalkulatorws.wsdl Źródło: dok. gsoap 13
WebService - zaczynamy // Contents of file "kalk_serv.c": #include "soaph.h" #include <math.h> //dla sqrt // implementacja funkcji dodaj int ns dodaj (struct soap *soap, double a, double b, double *result) *result = a + b; return SOAP_OK; // implementacja funkcji odejmij int ns odejmij (struct soap *soap, double a, double b, double *result) *result = a - b; return SOAP_OK; // implementacja funkcji mnoz int ns mnoz (struct soap *soap, double a, double b, double *result) *result = a * b; 14 return SOAP_OK; Źródło: dok. gsoap
WebService - zaczynamy // implementacja funkcji potega int ns potega (struct soap *soap, double a, double *result) *result = a * a; return SOAP_OK; // implementacja funkcji dziel int ns dziel (struct soap *soap, double a, double b, double *result) if (b!= 0) *result = a / b; return SOAP_OK; else return soap_sender_fault (soap, "Błąd dzielenia przez 0", "Parametr b musi być różny od 0"); 15
WebService - zaczynamy //implementacja funkcji pierwiastek int ns pierwiastek (struct soap *soap, double a, double *result) if (a >= 0) *result = sqrt (a); return SOAP_OK; else return soap_sender_fault (soap, "Podstawa pierwiastka mniejsza od 0!", "Podaj parametr a >=0"); // As always, a namespace mapping table is needed: struct Namespace namespaces[] = // "ns-prefix", "ns-name" "SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "xsi", "http://www.w3.org/2001/xmlschema-instance", "xsd", "http://www.w3.org/2001/xmlschema", "ns", "urn:kalkulator", // bind "ns" namespace prefix NULL, NULL ; 16
WebService - zaczynamy int main () struct soap soap; soap_init (&soap); soap_serve (&soap); exit (0); Kompilujemy: gcc -Wall -o akalk.cgi akalk.c soapc.c soapserver.c -lgsoap -lm cp akalk.cgi /var/www/cgi-bin/ (musimy mieć prawo do zapisu) Źródło: dok. gsoap 17
WebService - zaczynamy Tworzymy pierwszego klienta wsdl2h -s -c -o kalkulator.h../kalk_serv/kalkulatorws.wsdl Wygeneruje nam się plik nagłówkowy kalkulator.h a w nim: int ns1 dodaj( double a, ///< Request parameter double b, ///< Request parameter double *result ///< Response parameter ); int ns1 odejmij( double a, ///< Request parameter double b, ///< Request parameter double *result ///< Response parameter ); Źródło: wikipedia 18
WebService - zaczynamy int ns1 mnoz( double a, ///< Request parameter double b, ///< Request parameter double *result ///< Response parameter ); int ns1 dziel( double a, ///< Request parameter double b, ///< Request parameter double *result ///< Response parameter ); int ns1 pierwiastek( double a, ///< Request parameter double *result ///< Response parameter ); int ns1 potega( double a, ///< Request parameter double *result ///< Response parameter ); 19
WebService - zaczynamy soapcpp2 -C -c -s kalkulator.h Wygenerują nam się pliki szkieletorka :) calc.nsmap *.xml soapc.c soapclient.c tu znajdziemy funkcje które musimy wywołać soapclientlib.c soaph.h soapstub.h Źródło: wikipedia 20
WebService - zaczynamy #include <stdio.h> #include "soaph.h" #include "kalkulatorws.nsmap" #include "soapclient.c" int main () double par1 = 3; double par2 = 4; double wy = 0; struct soap ssoap; char *webaddr = "http://localhost:80/cgi-bin/akalk.cgi"; //można NULL wtedy brana wartość domyślna z wsdl soap_init (&ssoap); 21
WebService - zaczynamy if (soap_call_ns1 dodaj (&ssoap, webaddr, "", par1, par2, &wy) == SOAP_OK) printf ("Wynik %f+%f=%f\n", par1, par2, wy); else soap_print_fault (&ssoap, stderr); // itp... soap_end (&ssoap); soap_done (&ssoap); exit (0); Kompilacja: gcc -Wall -o kalkulator kalkulator.c soapc.c -lgsoap Uruchomienie:./kalkulator 22
WebService - zaczynamy int main () //Wersja serwisu niezależnego (standalone, selfhost) struct soap soap; // niezaininicjowana strukutra soap int m, s; // sokety mastera i slave'a soap_init (&soap);// inicjiowanie struktury soap m = soap_bind (&soap, NULL, 8081, 100); //soap,adres,port,maksymalny rozmiar kolejki if (m < 0) soap_print_fault (&soap, stderr); else int i; fprintf (stderr, "Serwer nasłuchuje: master socket = %d\n",m); for (i = 1;; i++) s = soap_accept (&soap); if (s < 0) soap_print_fault (&soap, stderr); break; fprintf (stderr,"%d: przyszło połaczenie z IP=%ld.%ld.%ld.%ld socket=%d\n",i, (soap.ip >> 24) & 0xFF, (soap.ip >> 16) & 0xFF,(soap.ip >> 8) & 0xFF, soap.ip & 0xFF, s); if (soap_serve (&soap)!= SOAP_OK) // żądanie obsługi soap_print_fault (&soap, stderr); // wyświetlenie błędu fprintf (stderr, "Żądanie obsłużone\n"); soap_destroy (&soap); // wyczyszczenie interfejsu soap_end (&soap); // wyczyszczenie wszystkiego i zamknięcie socketów soap_done (&soap); exit(0); 23
WebService C# Serwer Uruchamiamy Visual Web Developer lub VS pro File->New Web Site 24
WebService C# Serwer Dopiszmy do Service.cs prostą metodę [WebMethod] public double dodaj(double a, double b) return a + b; Build->Build Web Site Ctrl+F5 uruchamiamy nasz Pierwszy Webservice 25
WebService C# Serwer Można jeszcze zmienić WebService Namespace na swój, dodać Description i dodać swój namespace namespace MojWebserwis [WebService(Namespace = "http://localhost", Description= "To jest przykładowy webservice")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]... Wtedy do poprawy także plik Service.asmx <%@ WebService Language="C#" CodeBehind="~/App_Code/Service.cs" Class="MojWebserwis.Service" %> 26
WebService C# Serwer By uzewnętrznić nasz WebService wchodzimy w menu VS Website->ASP.NET Configuration Otworzy nam się strona z konfiguracją wybieramy zakładkę Security klikamy w Select authentication type zmieniamy na From the Internet klikamy Done. 27
Otwieramy Visual Studio C# Nowy Projekt WebService C# Klient 28
Projektujemy formatkę WebService C# Klient 29
WebService C# Klient Uruchamiamy nasz WebSewice Klikamy w Service Description Zapamiętujemy adres np: http://localhost:1487/website6/service.asmx?wsdl 30
WebService C# Klient W solution Explorerze klikamy prawym na MojKlientWS i wybieramy Add Service Reference Wklejamy zapamiętany link link do do WSDL'a lub lub wpisujemy adres adres interesującego nas nas WSDL'a 31
WebService C# Klient Po naciśnięciu Go pobierze nam informacje jakie metody są udostępnione. (Rozwinąć drzewko Service). Można też zmienić NameSpace np. na MojWS Przechodzimy do projektu formatki Dwukrotnie klikając w przycisk Hello przechodzimy do edycji zdarzenia związanego z kliknięciem. Uzupełniamy kod private void buttonhello_click(object sender, EventArgs e) MojWS.ServiceSoapClient mojws = new MojWS.ServiceSoapClient(); //MojWS.ServiceSoapClient() mojws = new MojWS.ServiceSoapClient("ServiceSoap","http://192.168.1.1/lokalizacja/service.asm x" MessageBox.Show(mojWS.HelloWorld()); Kompilacja F5 lub ctrl+f5 i podziwiamy efekty :) 32
WebService C# Klient Podobnie postępujemy dla przycisku Licz Dwukrotnie klikając w przycisk Licz Przechodzimy do edycji zdarzenia związanego z kliknięciem. Uzupełniamy kod private void buttonlicz_click(object sender, EventArgs e) MojWS.ServiceSoapClient mojws = new MojWS.ServiceSoapClient(); try MessageBox.Show(mojWS.dodaj(Double.Parse(textBoxA.Text ), Double.Parse(textBoxB.Text)).ToString()); catch (Exception ex) MessageBox.Show("Coś nie tak: " + ex.message); Kompilacja F5 lub ctrl+f5 i jeszcze raz podziwiamy efekty :) 33
WebService C# Instalacja websewisu na IIS Otwieramy IIS Managera (panel sterowania->narzędzia administracyjne-> Prawym Prawym klawiszem klawiszem klikamy klikamy w w Domyślna Domyślna witryna witryna sieci sieci Web- Web- >Nowy->Katalog >Nowy->Katalog wirtualny wirtualny Kreatorem Kreatorem wskazujemy wskazujemy gdzie gdzie ma ma znajdować znajdować się się nasz nasz WS WS np. np. webserwisy webserwisy Przenosimy Przenosimy cały cały nasz nasz projekt projekt do do wskazanego wskazanego katalogu katalogu Wpisujemy w przeglądarce http://nasz.adres.pl/webserwisy/service.asmx i ponownie się cieszymy :) 34
WebService C# końcowe uwagi W przypadku gdy nie znajdziemy IIS w systemie trzeba go doinstalować (domyślnie brak) Panel Sterowania->dodaj usuń programy->składniki systemu Windows Wybieramy Sieciowe usługi informacyjne Można wyłączyć z tego mail czy np. ftp Jeżeli IIS instalowaliśmy po instalacji VS trzeba wejść w Windows/Microsoft.NET\Framework\v2.0.50727> i wykonać polecenie aspnet_regiis -i 35