Programowanie Systemów Rozproszonych - WCF

Transkrypt

Programowanie Systemów Rozproszonych - WCF
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Programowanie Systemów Rozproszonych - WCF
Paweł Paduch
Politechnika Świętokrzyska
15 kwietnia 2016
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
1 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Plan wykładu
1
Wstęp
Literatura
Wprowadzenie
2
Przykład
Serwis
Program Hostujący
Klient
3
Hostowanie
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
4
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
2 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Literatura
Strony dokumentacji MS https://msdn.microsoft.com/enus/library/dd456779(v=vs.110).aspx
Andrew Troelsen - Język C# 2010 i platforma .NET 4
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
3 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Wstęp
WCF – (ang. Windows Communication Foundation) framework do
budowania aplikacji opartej o serwisy. Używając WCF można
wysyłać dane jako asynchroniczne komunikaty z jednego punktu
końcowego (ang. Endpoint) do drugiego.
To samo API wykorzystuje się do stworzenia komunikacji pomiędzy
aplikacjami na tym samym komputerze, komputerami lokalnej czy
globalnej sieci.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
4 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Zastosowania
Przykłady zastosowań:
Bezpieczne serwisy do przetwarzania informacji biznesowych
Serwisy dostarczające bieżące dane np. o ruchu ulicznym czy
serwisy monitorujące
Komunikatory
Aplikacje analityczne pobierające dane z wielu serwisów
Wystawienie obiegu zleceń (workflow)
Aplikacje silverlight zasilane z danych wystawionych przez
serwis.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
5 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Model
WCF bazuje na pojęciu komunikacji opartej na przesyłaniu
wiadomości i wszystko co może być wymodelowane jako komunikat
(np. żądanie http lub kolejka komunikatów – MSMQ) może być
reprezentowane w uniwersalnym modelu programowania. Dlatego
można wykorzystać jedno API do różnego mechanizmu
transportowego.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
6 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Model
W modelu możemy wyróżnić:
klientów, którzy inicjują komunikację
serwisów, aplikacji które czekają i odpowiadają na zgłoszenia
klientów.
pojedyncza aplikacja może działać jednocześnie jako klient i
serwer np. Duplex Services lub Peer-to-Peer Networking.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
7 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Endpoints
Endpoints – to punkty pomiędzy którymi komunikaty są
wymieniane (wysyłka i/lub odbiór). Definiują one wszystkie
informacje potrzebne do wymiany wiadomości.
Serwis zwykle wystawia jeden lub kilka punktów końcowych
aplikacji jak również 0 lub więcej punktów końcowych
infrastruktury.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
8 z 57
Wstęp
Przykład
Hostowanie
Inne
Literatura
Wprowadzenie
Endopoint
Endopoint - może być częścią serwisu działającego ciągle np.
osadzonego na IIS lub hostowany w aplikacji.
Endpointem może być też klient zgłaszający się do serwera. Klient
generuje endpoint kompatybilny z jednym z endpointów serwisu.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
9 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Nowy projekt
Tworzymy nową solucję WCFWyklad a w niej projekt
CalcServiceLibrary typu WCF Library
Rysunek: Nowy projekt
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
10 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Modyfikacje
Zmieniamy nazwy IService1 i Service na ICalc i Calc
Modyfikujemy linijkę a App.config:
Listing 1: Zmiana w app.config
1
<add baseAddress="http://localhost:8733←/Design_Time_Addresses/CalcServiceLibrary/Calc/" />
Usuwamy wygenerowany przykład „Echa”
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
11 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Interfejs
Tworzymy nowy interfejs
Listing 2: ICalc.cs
1
2
3
4
5
[ServiceContract(Namespace ="http://achilles.tu.kielce.pl")]
public interface ICalc
{
[OperationContract]
double Add(double a, double b);
6
[OperationContract]
double Sub(double a, double b);
7
8
9
[OperationContract]
double Mul(double a, double b);
10
11
12
[OperationContract]
double Div(double a, double b);
13
14
15
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
12 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Implementacja interfejsu
Tworzymy implementację
Listing 3: Calc.cs
1
2
public double Add(double a, double b)
{
return a + b;
}
3
4
5
6
public double Div(double a, double b)
{
if (b == 0) throw new DivideByZeroException("←parametr b nie moze byc 0");
return a / b;
}
7
8
9
public double Mul(double a, double b)
{
return a * b; }
10
11
12
public double Sub(double a, double b)
{
return a - b;
}
Można przetestować serwis (F5)
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
13 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Nowy projekt
Dodajemy nowy projekt do solucji typu Console Application
Dodajemy referencję do projektu
Dodajemy referencję do System.ServiceModel
Dodajemy odpowiednie using do Program.cs:
Listing 4: Dodatkowe przestrzenie nazw
1
2
3
using CalcServiceLibrary;
using System.ServiceModel;
using System.ServiceModel.Description;
4
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
14 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Main
Listing 5: Adres oraz instancja serwisu
1
Uri baseAddress = new Uri("http://localhost:8000/CalculatorService/")←;
2
3
ServiceHost selfHost = new ServiceHost(typeof(Calc), baseAddress);
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
15 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Main
Ustanawiamy punkt końcowy usługi oraz umożliwiamy
wymianę metadanych:
Listing 6: Endpoint i wymiana danych
1
2
// Dodajemy Endopoint uslugi
selfHost.AddServiceEndpoint(typeof(ICalc), new WSHttpBinding(), ←"CalculatorService");
3
4
5
6
7
// Umozliwiamy wymiane metadanych
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
16 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Main
Startujemy i zamykamy serwis
Listing 7: Start i zamknięcie serwisu
1
2
3
4
5
selfHost.Open();
Console.WriteLine("Serwis dziala....");
Console.WriteLine("Nacisnij <ENTER> by zakonczyc.");
Console.WriteLine();
Console.ReadLine();
6
7
selfHost.Close();
Można ustawić startup na bieżący projekt i uruchomić (F5)
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
17 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Nowy projekt
Dodajemy nowy projekt WPF
Z Toolboxa po lewej dodajemy 3 razy textbox (textBoxA,
textBoxB, textBoxWynik) Ten ostatni można dać Disabled
Dodajemy 4 guziki (buttonPlus, buttonMinu, buttonMnoz,
buttonDziel ja na rysunku 2
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
18 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Referencje i implementacja
Uruchamiamy hosta z usługą w trybie bez debugowania
(ctrl+F5)
Dodajemy referencje do System.ServiceModel oraz service
reference podając adres gdzie host wystawił naszą usługę
Dodajemy using CalculatorClient.CalcServiceReference; do
MainWindowXaml.cs
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
19 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Implementacja
W konstruktorze MainWindow dodajemy:
Listing 8: Start serwisu
1
2
3
4
5
6
7
8
9
10
11
12
public MainWindow()
{
InitializeComponent();
try
{
klient = new CalcServiceReference.CalcClient();
}
catch (Exception ex)
{
MessageBox.Show("nie udalo sie stworzyc klienta ←CalcServiceReference. " + ex.Message);
}
}
dodajemy prywatne pole CalcClient klient = null;
dodajemy obsługę ClosingWindow gdzie umieszczamy
klient.Close();
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
20 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Pobierz liczby
Piszemy funkcję pobierającą dane z Textboxów
Listing 9: pobierzLiczby
1
2
3
4
bool pobierzLiczby(out double a, out double b)
{
b = 0;
a = 0;
5
if (!double.TryParse(textBoxParamA.Text, out a))
{
MessageBox.Show("niepoprawna liczba a");
return false;
}
if (!double.TryParse(textBoxParamB.Text, out b))
{
MessageBox.Show("niepoprawna liczba b");
return false;
}
return true;
6
7
8
9
10
11
12
13
14
15
16
17
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
21 z 57
Wstęp
Przykład
Hostowanie
Inne
Serwis
Program Hostujący
Klient
Obsługa guzików
Dodajemy i podpinamy funkcje do obsługi zdarzeń kliknięć
Listing 10: Obsługa kliknięcia na guziku dodawania
1
2
3
4
5
6
7
8
private void buttonPlus_Click(object sender, RoutedEventArgs e)
{
double a, b;
if (pobierzLiczby(out a, out b))
{
textBoxWynik.Text = klient.Add(a, b).ToString();
}
}
Jeżeli program hostujący uruchomiony możemy uruchomić
naszego klienta (F5)
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
22 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Przygotowanie nowej strony
Otwieramy menadżera IIS
Dodajemy nową stronę
Rysunek: Nowa strona
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
23 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Zmiana architektóry
Dwukrotnie klikamy na puli aplikacji
Zmieniamy na .Net 4.0
Rysunek: Zmiana architektury na .Net 4.0
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
24 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy automatyczny
Tworzymy nowy projekt WCF Service App
Wybieramy publikuj i klikamy custom.
Rysunek: Publikacja serwisu
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
25 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy automatyczny
Wpisujemy odpowiednie dane...
Rysunek: Dane do publikacji
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
26 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy automatyczny - problem
...i mamy pierwszy problem
Rysunek: Nie można połączyć
Należy włączyć Usługę zarządzania siecią Web - wmsvc
Doinstalować też Web Deployment Tool
https://technet.microsoft.com/plpl/library/dd569059(v=ws.10).aspx co spowoduje dodanie
usługi „Web Deployment Agent Service” msdepsvc.
Otworzyć na firewallu port 8172
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
27 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy ręczny
Do CalcServiceLibrary dodaje plik Service.svc
Listing 11: Service.svc
1
<%@ServiceHost language="C#" Debug="true" Service="←CalcServiceLibrary.Calc"%>
Dodajemy też Web.config
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
28 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy ręczny
Listing 12: Web.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!-- This section is optional with the default configuration
model introduced in .NET Framework 4 -->
<service name="CalcServiceLibrary.Calc"
behaviorConfiguration="DefaultBehavior">
<!-- This endpoint is exposed at the base address provided by host:
<endpoint address=""
binding="wsHttpBinding"
contract="CalcServiceLibrary.ICalc" />
<!-- The mex endpoint is exposed at http://localhost/webservices/service.svc/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors >
<behavior name="DefaultBehavior">
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<!-- <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>-->
<serviceMetadata httpGetEnabled="true" />
http://localhost/webservices/service.svc
-->
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
29 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Deploy ręczny
W katalogu gdzie wskazuje strona np.
C:\inetpub\wwwroot\webservices\TestService wgrać pliki
service.svc , Web.config oraz katalog bin.
Jeżeli web config jest ok to powinno zadziałać. Uruchamiamy
Developer Command Prompt for VS2015 i tam wpisujemy
wcftestclient.exe podajemy adres naszej strony svc.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
30 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Nowy projekt usługi windows
Tworzymy nowy projekt nazwa CalcWindowsService
Rysunek: Nowy projekt usługi windows
Zmieniamy Service1 na CalcWinService
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
31 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Nadanie nazwy usłudze
W CalcWindowsService.Designer.cs zmieniamy nazwę usługi
Listing 13: CalcWindowsService.Designer.cs
1
2
3
4
5
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "CalcWindowsService";
}
W CalcWinService.cs dodajemy referencje do
System.ServiceModel i System.ServiceModel.Description i
zmienną
Listing 14: CalcWinService.cs
1
private ServiceHost m_svcHost = null;
Dodajemy referencje do proj CalcServiceLibrary i wstawiamy
using o tej samej nazwie.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
32 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Metoda OnStart
Wypełniamy metodę OnStart w CalcWinService.cs
Listing 15: CalcWinService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected override void OnStart(string[] args)
{
if (m_svcHost != null) m_svcHost.Close();
string strAdrHTTP = "http://localhost:9001/CalcService";
string strAdrTCP = "net.tcp://localhost:9002/CalcService";
Uri[] adrbase = { new Uri(strAdrHTTP), new Uri(strAdrTCP) };
m_svcHost = new ServiceHost(typeof(Calc), adrbase);
ServiceMetadataBehavior mBehave = new ServiceMetadataBehavior();
m_svcHost.Description.Behaviors.Add(mBehave);
BasicHttpBinding httpb = new BasicHttpBinding();
m_svcHost.AddServiceEndpoint(typeof(ICalc), httpb, strAdrHTTP);
m_svcHost.AddServiceEndpoint(typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
NetTcpBinding tcpb = new NetTcpBinding();
m_svcHost.AddServiceEndpoint(typeof(ICalc), tcpb, strAdrTCP);
m_svcHost.AddServiceEndpoint(typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
m_svcHost.Open();
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
33 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Metoda OnStop
Wypełniamy metodę OnStop w CalcWinService.cs
Listing 16: CalcWinService.cs
1
2
3
4
5
6
7
8
protected override void OnStop()
{
if (m_svcHost != null)
{
m_svcHost.Close();
m_svcHost = null;
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
34 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Dodanie instalatora usługi
Otworzyć CalcWinService w trybie designera
Prawym klawiszem otworzyć menu kontekstowe i wybrać „add
installer”
Rysunek: Dodanie instalatora
Zmieniamy nazwę ProjectInstaller na CalcServiceInstaller
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
35 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
CalcServiceInstaller
Kalwiszem F7 przełączmy się na kod i uzupełniamy go
Listing 17: CalcServiceInstaller.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
public CalcServiceInstaller()
{
// InitializeComponent();
serviceProcessInstaller1 = new ServiceProcessInstaller();
serviceProcessInstaller1.Account = ServiceAccount.LocalSystem;
serviceInstaller1 = new ServiceInstaller();
serviceInstaller1.ServiceName = "CalcWinService";
serviceInstaller1.DisplayName = "Kalkulator Serwis";
serviceInstaller1.Description = "WCF Kalkulator Serwis, ←przykladowy serwis hostowany w usludze windows";
serviceInstaller1.StartType = ServiceStartMode.Automatic;
Installers.Add(serviceProcessInstaller1);
Installers.Add(serviceInstaller1);
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
36 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Instalacja i start usługi
Otwieramy Command Prompt z uprawnieniami administratora
i przechodzimy do katalogu gdzie znajduje się
CalcWindowsService.exe
Wykonujemy polecenie: InstallUtil CalcWindowsService.exe
Start usługi: sc start CalcWinService lub z menadżera usług:
Rysunek: Zarządzanie usługami
usługa powinna być widoczna pod
http://localhost:9001/CalcService
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
37 z 57
Wstęp
Przykład
Hostowanie
Inne
IIS - Automatycznie
IIS - Ręcznie
Usługa Windows
Zatrzymanie i usunięcie usługi
Zatrzymanie sc stop CalcWinService
Usunięcie InstallUtil /u CalcWindowsService.exe
Mamiętaj! Gdy zmieniamy nazwę usługi należy ją najpierw
odinstalować przed skompilowaniem nowej wersji ponieważ
deinstalator posługując się plikiem exe nie znajdzie usługi o
starej nazwie
Można ewentualnie też tak:
net stop ”ServiceName”
sc delete ”ServiceName”
Gdyby był błąd 1072 to trzeba sprawdzić czy nie ma
uruchomionego menadżera usług, mmc lub ProcessExplorera
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
38 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Nowy projekt Web Site
Do solucji dodajemy nowy web site (z menu kontekstowego
wybieramy add new web site)
Rysunek: Nowy Web Site
Do projektu dodajemy nowy formularz Web Form i
zostawiamy nazwę Default.aspx
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
39 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Formatka
Uzupełniamy kod dodanej formatki Default.aspx
Listing 18: Default.aspx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"
Text="Wartosc 1 : "></asp:Label>
<asp:TextBox ID="txtVal1" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label2" runat="server"
Text="Wartosc 2 : "></asp:Label>
<asp:TextBox ID="txtVal2" runat="server"></asp:TextBox>
<br />
<asp:Button ID="btnCalc" runat="server"
onclick="btnCalc_Click" Text="Oblicz"
Width="91px" />
<br />
<asp:Label ID="lblOutput" runat="server"
BorderStyle="None" Height="152px"
Width="606px"></asp:Label>
</div>
</form>
</body>
</html>
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
40 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Service Reference
Dodajemy referencje do serwisu
Rysunek: Nowy Web Site
Stworzy nam to katalog App WebReferences oraz zmodyfikuje
web.config
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
41 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Default.aspx.cs
Listing 19: Default.aspx.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
protected void btnCalc_Click(object sender, EventArgs e)
{
double dblX = 0, dblY = 0;
bool b1 = double.TryParse(txtVal1.Text, out dblX);
bool b2 = double.TryParse(txtVal2.Text, out dblY);
if ((b1) && (b2))
{
StringBuilder sbTmp = new StringBuilder("<font size=3 color=#000080>");
sbTmp.Append("<p>Wprowadzono<br>Wartosc 1 : " + dblX.ToString("F2"));
sbTmp.Append("<br>Wartosc 2 : " + dblY.ToString("F2"));
sbTmp.Append("<p>Obliczam za pomoca HTTP Binding");
ServiceReferenceCalc.CalcClient calcProxy1 = new ServiceReferenceCalc.CalcClient("BasicHttpBinding_ICalc");
double dblResult = calcProxy1.Add(dblX, dblY);
sbTmp.Append("<br>Wolam Add >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy1.Sub(dblX, dblY);
sbTmp.Append("<br>Wolam Sub >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy1.Mul(dblX, dblY);
sbTmp.Append("<br>Wolam Mul >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy1.Div(dblX, dblY);
sbTmp.Append("<br>Wolam Div >");
sbTmp.Append(dblResult.ToString());
ServiceReferenceCalc.CalcClient calcProxy2 = new ServiceReferenceCalc.CalcClient("NetTcpBinding_ICalc");
sbTmp.Append("<p>Obliczam za pomoca NetTcp Binding");
dblResult = calcProxy2.Add(dblX, dblY);
sbTmp.Append("<br>Wolam Add >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy2.Sub(dblX, dblY);
sbTmp.Append("<br>Wolam Sub >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy2.Mul(dblX, dblY);
sbTmp.Append("<br>Wolam Mul >");
sbTmp.Append(dblResult.ToString());
dblResult = calcProxy2.Div(dblX, dblY);
sbTmp.Append("<br>Wolam Div >");
sbTmp.Append(dblResult.ToString());
lblOutput.Text = sbTmp.ToString();
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
42 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Przekazywanie wyjątków do klienta
Jeżeli chcemy przekazać klientowi wyjątek wygenerowany po
stronie serwera należy zmodyfikować zachowanie serwisu
Można to zrobić z poziomu kodu
Listing 20: Włączenie przekazywania szczegółów wyjątków
1
2
3
4
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Find<ServiceDebugBehavior>().←IncludeExceptionDetailInFaults = true;
selfHost.Description.Behaviors.Add(smb);
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
43 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Przekazywanie wyjątków do klienta
Można to zrobić w konfiguracji serwisu
Listing 21: Włączenie przekazywania szczegółów wyjątków
1
2
3
4
5
6
7
8
<!-- To receive exception details in faults for debugging ←purposes,
set the value below to true. Set to false before ←deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
9
10
</configuration>
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
44 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Zwracanie błędu
Aby przekazać bład do klienta można posłużyć się klasą
FaultException
Listing 22: Przekazywanie błedów do klientów
1
throw new FaultException("Nie dziel przez 0!", new FaultCode("Zle ←parametry wejsciowe!"));
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
45 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Duplex Contract
Duplex Service Contract jest paternem dwukierunkowej
wymiany komunikatów pomiędzy dwoma endpointami
Duplex Service może odesłać wiadomość do klienta poprzez
kanał zwrotny, który klient udostępnia serwisowi.
Żeby stworzyć kontrakt typu duplex potrzebujemy pary
interfejsów.
Pierwszym jest Service Contract Interface, który opisuje
operacje jaki klient może wywoływać na serwisie.
W tym kontrakcie definiujemy też interfejs dla klienta tzw.
Callback Contract w atrybucie
ServiceContractAttribute.CallbackContract
Callback Contract jest interfejsem opisującym co może serwis
zrobić u klienta.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
46 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Nowy projekt
Dodajemy nowy projekt WCF Service Application o nazwie
WCFTestApp
Rysunek: Nowy projekt WCF
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
47 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Zmiana nazw
Service1 zmieniamy na DuplexTest
modyfikujemy zawartość DuplexTest.svc (prawy klawisz myszy
,,View Markup”) Zamieniamy Service1 na DuplexTest
usuwamy domyślną zawartość w plikach *.cs
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
48 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Definicja Interfejsów
W pliku IDuplexText.cs Definiujemy dwa interfejsy wraz z
odpowiednimi atrybutami:
Listing 23: Interfejsy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Runtime.Serialization;
System.ServiceModel;
System.ServiceModel.Web;
System.Text;
namespace DuplexTestApp
{
public interface IKontraktZwrotny
{
[OperationContract(IsOneWay = true)]
void FunkcjaZwrotna(string str);
}
[ServiceContract (CallbackContract = typeof(IKontraktZwrotny))]
public interface IDuplexTest
{
[OperationContract(IsOneWay = true)]
void DodajSlowo(string str);
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
49 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Implementacja DuplexTest.cs
W pliku DuplexTest realizujemy zadany interfejs.
Listing 24: DuplexTest.svc.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Runtime.Serialization;
System.ServiceModel;
System.ServiceModel.Web;
System.Text;
namespace DuplexTestApp
{
public class DuplexTest : IDuplexTest
{
IKontraktZwrotny callback = null;
List<string> listaSlow = null;
public DuplexTest()
{
listaSlow = new List<string>();
callback = OperationContext.Current.GetCallbackChannel<IKontraktZwrotny>();
}
public void DodajSlowo(string str)
{
if (listaSlow != null) listaSlow.Add(str);
callback.FunkcjaZwrotna("Otrzymalem slowo: " + str + ". Liczba slow: " + listaSlow.Count());
}
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
50 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Implementacja DuplexTest.cs
W pliku Web.config modyfikujemy konfiguracje tak by serwis
obsługiwał tryb duplex, dodajemy nasz serwis
Listing 25: Web.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name ="duplexbehav">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="DuplexTestApp.DuplexTest" behaviorConfiguration="duplexbehav">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9000/DuplexTest"/>
</baseAddresses>
</host>
<endpoint name ="duplexendpoint"
address=""
binding="wsDualHttpBinding"
contract="DuplexTestApp.IDuplexTest"/>
<endpoint name ="MetaDataTcpEndpoint"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
51 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Uruchomienie
Można prawym klawiszem myszy otworzyć menu kontekstowe na
pliku e i wybrać View in Browser
Możemy też hostawać serwis na IIS jak pokazano na innych
slajdach.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
52 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Klient
Mając uruchomiony serwis, tworzymy nową aplikację konsolową:
Dodaj nowy projekt o nazwe DuplexTestProgram
Dodaje referencje do System.ServiceModel oraz service
reference do naszej usługi
Np. http:anakin.kin.tu.kielce.pl:8002DuplexTest.svc
Nadajemy przestrzeń nazw dla nowej referencji DuplexTestRef
Do programu dodajemy nową klasę Odpowiadacz
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
53 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Klasa Odpowiadacz
Listing 26: Odpowiadacz.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.ServiceModel;
DuplexTestProgram.DuplexTestRef;
namespace DuplexTestProgram
{
class Odpowiadacz : IDuplexTestCallback, IDisposable
{
DuplexTestClient proxy;
public void FunkcjaZwrotna(string str)
%{
Console.WriteLine("Zwrotnie dostalem: " + str);
}
public void zawolajSerwis(string str)
{
InstanceContext context = new InstanceContext(this);
proxy = new DuplexTestClient(context);
proxy.DodajSlowo(str);
}
public void Dispose()
{
proxy.Close();
}
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
54 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Główny program
Listing 27: Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
namespace DuplexTestProgram
{
class Program
{
static void Main(string[] args)
{
Odpowiadacz odp = new Odpowiadacz();
odp.zawolajSerwis("kuku");
Console.ReadLine();
odp.Dispose();
}
}
}
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
55 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
Pytania
?
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
56 z 57
Wstęp
Przykład
Hostowanie
Inne
Web Site
Przekazywanie informacji o błędzie do klienta
Komunikacja dwukierunkowa - Duplex
koniec
Dziękuję Państwu za uwagę.
Paweł Paduch
Programowanie Systemów Rozproszonych - WCF
57 z 57