Skip to content

Zadania (41-44)

Przykład użycia usługi SOAP w aplikacji na platformie .NET w języku C#

Section titled “Przykład użycia usługi SOAP w aplikacji na platformie .NET w języku C#”

Załóżmy, że gdzieś w sieci działa usługa SOAP kalkulatora, która udostępnia operacje arytmetyczne. Jej kontrakt (czyli to, co usługa oferuje) wygląda tak:

// kontrakt usługi - operacje, które usługa udostępnia klientom
[ServiceContract]
public interface ICalculator
{
[OperationContract]
int Add(int a, int b);
[OperationContract]
int Subtract(int a, int b);
}

Żeby użyć tej usługi w swojej aplikacji, dodaje się do projektu referencję do usługi (Service Reference), podając jej adres. Na podstawie opisu usługi (WSDL) środowisko generuje klasę pośredniczącą zwaną proxy, np. CalculatorClient. Proxy ma te same metody co usługa, więc wywołuje się je jak zwykłe metody lokalne, a ono samo zamienia wywołanie na komunikat SOAP i wysyła przez sieć do usługi.

// utworzenie klienta proxy (wygenerowanego na podstawie WSDL usługi)
CalculatorClient client = new CalculatorClient();
// wywołanie zdalnych operacji usługi tak jak metod lokalnych
int sum = client.Add(2, 3);
int diff = client.Subtract(10, 4);
// wyniki przyszły z usługi przez sieć
Console.WriteLine(sum);
Console.WriteLine(diff);
// zamknięcie połączenia z usługą
client.Close();

Z perspektywy programisty cała komunikacja sieciowa jest ukryta: piszemy client.Add(2, 3) i dostajemy wynik, a proxy w tle buduje żądanie SOAP, wysyła je, czeka na odpowiedź i zwraca rozpakowany wynik.


Skrót do zapamiętania: Dodajemy referencję do usługi (z WSDL), środowisko generuje klasę proxy z metodami usługi, a zdalne operacje wywołujemy jak lokalne (client.Add(2, 3)). Proxy zamienia wywołanie na komunikat SOAP i wysyła go przez sieć.

  • Usługa ma kontrakt (operacje), np. ICalculator z Add/Subtract.
  • Dodanie Service Reference na podstawie adresu/WSDL.
  • Środowisko generuje klasę proxy odwzorowującą metody usługi.
  • Wywołanie zdalne wygląda jak lokalne: client.Add(2, 3).
  • Proxy zamienia wywołanie na komunikat SOAP i wysyła przez sieć (komunikacja ukryta).

Technologia WCF - rola, przeznaczenie, zalety

Section titled “Technologia WCF - rola, przeznaczenie, zalety”

WCF (Windows Communication Foundation) to ujednolicona platforma .NET do budowania i konsumowania aplikacji zorientowanych na usługi (SOA). Jej rolą jest dostarczenie jednego, spójnego modelu komunikacji między aplikacjami, który wcześniej był rozproszony po wielu osobnych technologiach (web services/SOAP, .NET Remoting, MSMQ, nazwane potoki). WCF łączy je pod wspólnym API.

Przeznaczeniem WCF jest tworzenie usług komunikujących się niezależnie od protokołu transportu i lokalizacji klienta. Do najważniejszych zalet należą: jeden jednolity model programowania niezależny od transportu, wsparcie wielu protokołów (HTTP, TCP, MSMQ, named pipes), wbudowane bezpieczeństwo, obsługa transakcji, niezawodne przesyłanie komunikatów oraz interoperacyjność z innymi platformami przez standardy web services.

Najlepiej widać to na hostowaniu usługi: tę samą klasę usługi można wystawić przez kilka różnych protokołów, dodając po prostu kolejne endpointy z innym bindingiem. Logika usługi się nie zmienia.

using System.ServiceModel;
// hostujemy tę samą usługę (CalculatorService)
ServiceHost host = new ServiceHost(typeof(CalculatorService));
// ten sam kontrakt wystawiony przez HTTP (SOAP)
host.AddServiceEndpoint(typeof(ICalculator), new BasicHttpBinding(),
"http://localhost/calc");
// ten sam kontrakt wystawiony przez TCP
host.AddServiceEndpoint(typeof(ICalculator), new NetTcpBinding(),
"net.tcp://localhost:8000/calc");
// ten sam kontrakt wystawiony przez named pipes (komunikacja lokalna)
host.AddServiceEndpoint(typeof(ICalculator), new NetNamedPipeBinding(),
"net.pipe://localhost/calc");
// uruchomienie usługi
host.Open();

Skrót do zapamiętania: WCF to jednolita platforma .NET do budowy usług (SOA), łącząca pod jednym API różne technologie komunikacji (SOAP, remoting, MSMQ, named pipes). Zalety: jeden model, wiele protokołów, bezpieczeństwo, transakcje, niezawodność, interoperacyjność.

  • Ujednolicona platforma do tworzenia i konsumpcji usług (SOA).
  • Łączy pod jednym API: web services/SOAP, remoting, MSMQ, named pipes.
  • Niezależność od transportu i lokalizacji klienta.
  • Zalety: jeden model, wiele protokołów, bezpieczeństwo, transakcje, niezawodne komunikaty, interoperacyjność.

WCF - architektura, model programowania, przykłady implementacji usług

Section titled “WCF - architektura, model programowania, przykłady implementacji usług”

Architektura WCF opiera się na pojęciu punktu końcowego (endpoint), który definiują trzy elementy określane skrótem ABC. Address (adres) mówi gdzie znajduje się usługa, Binding (powiązanie) określa jak się z nią komunikować (protokół transportu, kodowanie, bezpieczeństwo), a Contract (kontrakt) opisuje co usługa oferuje, czyli jej operacje. Usługa może być hostowana w IIS, w samodzielnej aplikacji (self-hosting) lub w WAS.

W modelu programowania kontrakt usługi definiuje się jako interfejs z atrybutem ServiceContract, a jego metody atrybutem OperationContract. Złożone dane przesyłane między klientem a usługą opisuje się atrybutem DataContract. Konkretna klasa implementuje interfejs kontraktu, dostarczając logikę operacji.

using System.ServiceModel;
// kontrakt usługi - interfejs oznaczony atrybutem ServiceContract
[ServiceContract]
public interface ICalculator
{
// operacja udostępniana przez usługę - atrybut OperationContract
[OperationContract]
int Add(int a, int b);
}
// implementacja usługi realizująca kontrakt
public class CalculatorService : ICalculator
{
// właściwa logika operacji usługi
public int Add(int a, int b)
{
return a + b;
}
}

Jeśli usługa przesyła złożone dane (własne klasy), opisuje się je atrybutem DataContract, a ich pola atrybutem DataMember. Tylko tak oznaczone składowe trafiają do komunikatu:

using System.Runtime.Serialization;
// złożony typ przesyłany między klientem a usługą
[DataContract]
public class Account
{
// pole włączone do komunikatu
[DataMember]
public int Id { get; set; }
[DataMember]
public decimal Balance { get; set; }
}

Aby usługa zaczęła działać, trzeba ją hostować i zarejestrować jej endpoint, czyli właśnie trójkę ABC. W self-hostingu robi to ServiceHost, gdzie argumenty AddServiceEndpoint odpowiadają kolejno Contract, Binding i Address:

using System.ServiceModel;
ServiceHost host = new ServiceHost(typeof(CalculatorService));
// endpoint = ABC: Contract (co), Binding (jak), Address (gdzie)
host.AddServiceEndpoint(
typeof(ICalculator), // Contract
new BasicHttpBinding(), // Binding
"http://localhost/calc"); // Address
host.Open();

Skrót do zapamiętania: Architektura WCF = endpoint opisany przez ABC: Address (gdzie), Binding (jak), Contract (co). Model: interfejs z [ServiceContract], metody z [OperationContract], dane z [DataContract]/[DataMember], klasa implementująca kontrakt. Endpoint rejestrujemy przy hostowaniu (ServiceHost.AddServiceEndpoint). Hosting: IIS, self-host, WAS.

  • Endpoint = ABC: Address (gdzie), Binding (jak), Contract (co).
  • [ServiceContract] na interfejsie, [OperationContract] na metodach.
  • [DataContract] dla złożonych danych przesyłanych w komunikatach.
  • Klasa implementuje interfejs kontraktu (logika operacji).
  • Hosting: IIS, self-hosting, WAS.

Przepływ transakcyjny (transaction flow) w WCF to mechanizm pozwalający, by klient i usługa uczestniczyli w jednej, wspólnej transakcji. Transakcja rozpoczęta po stronie klienta “przepływa” przez granicę usługi, dzięki czemu operacje wykonane u klienta i w usłudze są traktowane jako jedna niepodzielna całość (zgodnie z zasadami ACID): albo wszystkie zostaną zatwierdzone, albo wszystkie wycofane.

Aby przepływ transakcyjny działał, muszą współgrać trzy warunki: powiązanie (binding) musi go wspierać i mieć włączony (np. wsHttpBinding z transactionFlow ustawionym na true), operacja musi pozwalać na przepływ transakcji (atrybut TransactionFlow), a implementacja operacji musi działać w ramach transakcji (TransactionScopeRequired ustawione na true w OperationBehavior). Pod spodem WCF korzysta ze standardu WS-AtomicTransaction, a transakcje rozproszone koordynuje menedżer MSDTC.

Po stronie usługi oznacza się to dwoma atrybutami: w kontrakcie operacja pozwala na przepływ transakcji, a w implementacji wymusza działanie w transakcji:

[ServiceContract]
public interface IBankService
{
// operacja pozwala na przepływ transakcji od klienta
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Withdraw(decimal amount);
}
public class BankService : IBankService
{
// operacja musi działać w ramach transakcji
[OperationBehavior(TransactionScopeRequired = true)]
public void Withdraw(decimal amount) { }
}

Klient opakowuje wywołania usługi w TransactionScope. Dzięki przepływowi ta sama transakcja obejmuje operacje u klienta i w usłudze, a Complete zatwierdza całość naraz:

// jedna wspólna transakcja dla wielu wywołań usługi
using (TransactionScope scope = new TransactionScope())
{
client.Withdraw(100);
client.Withdraw(50);
// zatwierdzenie całości; bez Complete nastąpi rollback
scope.Complete();
}

Skrót do zapamiętania: Przepływ transakcyjny WCF pozwala klientowi i usłudze być w jednej transakcji (ACID, commit albo rollback razem). Wymaga: bindingu z transactionFlow=true, atrybutu TransactionFlow na operacji i TransactionScopeRequired=true w implementacji. Oparty na WS-AtomicTransaction + MSDTC.

  • Transakcja klienta przepływa do usługi -> wspólna, niepodzielna całość (ACID).
  • Wszystko commit albo wszystko rollback.
  • Warunki: binding wspiera (wsHttpBinding, transactionFlow=true).
  • Operacja: atrybut TransactionFlow; implementacja: TransactionScopeRequired=true.
  • Pod spodem: WS-AtomicTransaction, koordynacja przez MSDTC.