Przegląd najważniejszych elementów Windows Communication Foundation (WCF). Od wprowadzenia przez bardziej szczegółowe omówienie koncepcji bindingów, kontraktów, sposobów instancjonowania, obsługi błędów, bezpieczeństwa, itp.
Od obiektów dousług
Polimorfizm
Hermetyzacja
Dziedziczenie
Komunikat
Schemat + kontrakt + polisa
Szeroka współpraca
Położenie dowolne
Ścisły związek
Metadane w czasie działania
Obiektowe UsługiKomponentowe
1980 20001990
3.
Zadania serwera aplikacyjnego
•„Pojemnik” na obiekty realizujące daną funkcjonalnośd
– Jak pisad logikę obiektów?
• Infrastruktura: transakcje, sesje, stan…
• Mechanizmy komunikacji
• Skalowalnośd: platforma + „opcje dla programisty”
• Administrator:
– Nadzór nad działaniem „platformowym”
• Zużycie pamięci, procesora, wątki itp.
– Monitorowanie działania „biznesowego”
• O ile będzie rejestrowane w zrozumiały sposób…
Serwer aplikacyjny to urządzenie które dostarcza aplikację do
urządzeo klienckich (za Wikipedia).
Komputer dedykowany do wykonania określonych
programów/zadao.
+ architektura
4.
MTS
Komponenty
Runtime aplikacji
Deklaratywne transakcje
ibezpieczeostwo
Autoryzacja oparta o
role
COM+
Luźno powiązane zdarzenia
Komponentyu kolejkowane
„przepustnica” – nie więcej niż
x komponentów
Enterprise Services
Model programowania w kodzie
zarządzalnym
Oparty o atrybuty, deklaratywny,
konfiguracja w XML
Windows Communication
Foundation
• Komunikaty oparte o XML
• Dowolny transport
• Zorientowane na usługi
• Bezpieczeostwo: Federacja,
CardSpace (dowody tożsamości)
• Hosting - gdziekolwiek
Ewolucja usług aplikacyjnych
WCF: Adres, Binding,Kontrakt
Klient Usługa
KomunikatABC A B C
A B C
Adres Binding Kontrakt
(Gdzie) (Jak) (Co)
Endpoint
Endpoint
Endpoint
Encoder
Transport
BasicHttp, WSHttp,
WSDualHttp,
WSFederation
…Context…
NetTcp,
NetNamedPipe,
NetPeerTcp
NetMsmq,
MsmqIntegration
9.
WCF – standardowebindingi
Binding Interop Bezp. Sesja Trans. Duplex
BasicHttpBinding BP 1.1 N, T N N n/a
WSHttpBinding WS M, T, X N, T, RS N, Tak n/a
WSDualHttpBinding WS M RS N, Tak Tak
WSFederationBinding Federacja M N, RS N, Tak Nie
NetTcpBinding .NET T, M T ,RS N, Tak Tak
NetNamedPipeBinding .NET T T, N N, Tak Tak
NetPeerTcpBinding Peer T N N Tak
NetMsmqBinding .NET T, M, X N N, Tak Nie
MsmqIntegrationBinding MSMQ T N N, Tak n/a
N = Brak | T = Transport | M = Wiadomośd | B = Oba | RS = Pewna sesja
10.
WCF – podstawy(wyjaśnienie)
• Separacja kontraktu i implementacji
• Wzorce komunikacyjne
– Komunikacja jednokierunkowa (IsOneWay)
– Zwracanie wartości
– Sesja,
– Kontrakt „zwrotny” (po stronie klienta)
– Kontekst
• Separacja szczegółów komunikacyjnych
• Hosting: Jakkolwiek
11.
WCF na jednymslajdzie
Definicja „koocówki”
Adres + Binding +
Kontrakt
Definicja kontraktu
Implementacja usługi
[ServiceContract]
public interface IMyInterface {
[OperationContract]
void MyMethod();
[ServiceBehavior(
InstanceContextMode=Single]
public class MyService: IMyInterface {
[OperationBehavior(Impersonation =
ImpersonationOption.Required)]
public void MyMethod() { … }
<service name="MyService">
<endpoint
address=“net.tcp://localhost:1234/MySvc"
binding="netTcpBinding"
contract="IMyInterface" />o
12.
Kontrakt
• Definiują funkcjonalnośdusługi.
• Atrybuty kontraktu:
– ServiceContract
• OperationContract
– DataContract
– FaultContract
– MessageContract
• MessageBody
• MessageHeader
• Zachowania kontraktu
– Sesja, transakcje, sposób inicjacji…
13.
Kontrakt
• Możliwośd implementacjiwielu kontraktów
• Publiczny konstruktor
• [ServiceContract(Namespace = „”)+
– Domyślnie – tempuri.org
– Intranet – np. nazwa aplikacji
– Intenet – URL
• Nazwa metody usługi – domyślnie z klasy
– [OperationContract(Name = „…”)+
14.
Host
• IIS +WAS (Vista+, Windows Server 2008+)
– Zarządzanie, skalowalnośd, itp.
• IIS 5/6 – tylko HTTP
– Web.config – eksponowane usługi
• Self-hosting
– InProc – szczególny przypadek (klient i serwer w
tym samym procesie)
– Między procesami
– Między maszynami
15.
ServiceHost
public static voidMain( )
{
Uri baseAddress1 = new Uri("net. tcp: //localhost: 8001/");
ServiceHost host1 = new ServiceHost(typeof(MyService),
baseAddress1) ;
ServiceHost host = new ServiceHost(typeof(MyService));
host.Open( );
//Możliwe blokujące wywołania
Application.Run(new MyForm( ));
host.Close( );
}
// WcfSvcHost
16.
WAS
• Nie ograniczonydo HTTP
– Dowolny transport, port, kolejka
• Zalety vs self-hosting
– Application pooling, recycling, zarządzanie idle-
time, izolacja
– Zalecane, kiedy dostępne Windows Server 2008
• Interakcja z procesem hosta
<%@ ServiceHost
Language = "C#"
Debug = "true"
CodeBehind = "~/App_Code/MyService. cs"
Service = "MyService"
Factory = "MyServiceFactory" %>
17.
Service Factory
class MyServiceFactory: ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type
serviceType, Uri[] baseAddresses)
{
ServiceHost host = new ServiceHost(serviceType,
baseAddresses);
// Dodatkowe kroki – np. logowanie
return host;
}
}
Dziedziczenie
• Możliwe, ale*ServiceContract] nie jest dziedziczony
[ServiceContract]
interface ISimpleCalculator
{
[OperationContract]
int Add(int arg1, int arg2);
}
[ServiceContract]
interface IScientificCalculator : ISimpleCalculator
{
[OperationContract]
int Multiply(int arg1, int arg2);
}
// „Spłaszczane” po stronie klienta
// Możliwe ręczne przywrócenie hierarchii po stronie klienta i usunięcie atrybutów
// [OperationContract]
[OperationContract(Action = "... /ISimpleCalculator/Add",
ReplyAction = "... /ISimpleCalculator/AddResponse")]
int Add(int arg1, int arg2) ;
[OperationContract(Action = "... /IScientificCalculator/Multiply",
ReplyAction = "... /IScientificCalculator/MultiplyResponse")]
int Multiply(int arg1, int arg2) ;
33.
Zgodnośd z kontraktem
//Dynamiczna weryfikacja zgodności na podstawie WSDL
bool contractSupported = false;
Uri mexAddress = new Uri("...?WSDL") ;
ServiceEndpointCollection endpoints =
MetadataResolver. Resolve(typeof(ISimpleCalculator) ,
exAddress, MetadataExchangeClientMode. HttpGet) ;
if(endpoints. Count > 0)
{
contractSupported = true;
}
Wymiana danych
• Infoset– obsługiwane typy parametrów, …
• Serializacja w .NET
– [Serializable], [NonSerialized]
– BinaryFormatter, SoapFormatter – wymaga .NET i
konkretnego typu
– WCF – DataContractSerializer – nie udostępnia
informacji o typie; tylko kontrakt danych
• Wyłącznie serializowalne typy
– Klasa musi byd dostępna także po stronie klienta
36.
Atrybuty kontraktu danych
•Samo [Serializable] – zbyt ścisłe powiązanie
• [DataContract]
– Publikowane w MEX
[DataContract]
struct Contact
{
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
// *Dla uproszczenia bez właściwości
// Właściwości mogą być private, koniecznie get i set
Inne
• Współdzielenie kontraktu
–Problem: ten sam typ w 2 serwisach (przestrzenie nazw)
– „Reuse types in reference assemblies”
• Dziedziczenie
– [KnownType], [ServiceKnownType]
// Customer : Contact
Contact contact = new Customer( );
ContactManagerClient proxy = new ContactManagerClient( );
// Błąd w czasie działania
proxy.AddContact(contact) ;
proxy.Close( );
// ------------------------
[DataContract]
[KnownType(typeof(Customer))]
class Contact { ... }
[DataContract]
class Customer : Contact { ... }
39.
Współdzielenie kontraktu
• Zgodnośdz infoset - np. wersjonowanie
• Dostosowanie klasy właściwością Name
[DataContract(Name = "Contact")]
struct Person
{
[DataMember(Name = "FirstName")]
public string Name;
[DataMember(Name = "LastName")]
public string Surname;
}
40.
Współdzielenie a serializacja(1)
• Od najbardziej ogólnej do najbardziej
szczegółowej
• Pola – alfabetycznie
[DataContract]
class Contact
{
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
[DataContract]
class Customer : Contact
{
[DataMember]
public int CustomerNumber;
}
// Infoset: Firstname, Lastname, CustomerNumber
41.
Współdzielenie a serializacja(2)
[DataContract(Name = "Customer")]
public class Person
{
[DataMember(Name = "FirstName")]
public string Name;
[DataMember(Name = "LastName")]
public string Surname;
[DataMember]
public int CustomerNumber;
}
// Kolejność: CustomerNumber, Firstname, Lastname
[DataContract(Name = "Customer")]
public class Person
{
[DataMember(Name = "FirstName", Order = 1)]
public string Name;
[DataMember(Name = "LastName", Order = 1)]
public string Surname;
[DataMember(Order = 2)]
public int CustomerNumber;
}
// Kolejność zgodna z infoset: Firstname, Lastname, CustomerNumber
42.
Wersjonowanie kontraktu
• Dodawanienowych pól
– Nadmiarowośd jest dozwolona i kompatybilna
• Brakujące pola
– Wartości domyślne (null, itp.)
– [OnDeserializing]
– [DataMember(IsRequired = true)] – wyjątek
– Problem z przekazywaniem dalej – utracona
informacja
43.
Wersjonowanie c.d.
[DataContract]
class Contact: IExtensibleDataObject
{
ExtensionDataObject IExtensibleDataObject.ExtensionData
{ get; set; }
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
// Nie tracimy nadmiarowej informacji
// Umożliwia to interakcję z serwisem spodziewającym się innego
// kontraktu. Dlatego można wykluczyć taki scenariusz:
[ServiceBehavior(IgnoreExtensionDataObject = true)]
class ContactManager : IContactManager { ... }
// Najlepsza praktyka: zawsze obsługa IExtensibleDataObject
// unikać IgnoreExtensionDataObject
Per Call
• Bezstanowośd,skalowalnośd
– Konieczna inicjalizacja i zapis stanu
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{ ... }
Per Call isesja komunikacyjna
• Jeśli serwis ma tryb single-threaded i
włączone transport session, żądania
przetwarzane jeden po drugim
– Bez sesji – możliwa losowa kolejnośd na wyjściu
• Uwaga: Load Balancer i sesja
– Sticky Sessions
50.
Per Session
• Domyślnytryb
• Instancja utrzymywana w pamięci
– Skalowalnośd
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract { ... }
• Wymagane transport session
– Zalecane wymuszenie na poziomie kontraktu
public enum SessionMode
{
Allowed,
Required,
NotAllowed
}
[ServiceContract(SessionMode = SessionMode.Allowed)]
interface IMyContract {. . . }
51.
Singleton
• Tworzony wrazze startem procesu hosta
• Sesja nie wymagana
– Po zakooczeniu, nadal instancja w pamięci
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract { ... }
• Możliwe przekazanie zainicjalizowanej
instancji klasy do konstruktora hosta
Durable services
• Długotrwałeprocesy
– Wywołanie – długi czas oczekiwania - wywołanie
• Trwałe zapisywane stanu (np. baza danych)
– Serializacja – deserializacja
– Provider (domyślny lub własny)
• ID instancji
– Komunikaty aktywacyjne (jeśli brak ID)
– Komunikaty kooczące (usunięcie instancji)
<behaviors>
<serviceBehaviors>
<behavior name = "DurableService">
<persistenceProvider
type = "... type ... , ... assembly ... "
<!-- Provider-specific parameters -->
/>
</behavior>
</serviceBehaviors>
</behaviors>
55.
[Serializable]
[DurableService]
class MyCalculator :ICalculator
{
double Memory
{ get; set; }
[DurableOperation(CanCreateInstance = true)]
public double Add(double number1, double number2)
{
return number1 + number2;
}
public void MemoryStore(double number)
{
Memory = number;
}
[DurableOperation(CompletesInstance = true)]
public void MemoryClear()
{
Memory = 0;
}
//Rest of the implementation
}
56.
Throttling
• Tymczasowe pikiw obciążeniu
– Kolejkowanie, spłaszczenie piku
• Nie działa w przypadku stałego zwiększenia obciążenia
• Możliwe do konfiguracji: maxConcurrentCalls,
maxConcurrentSessions, maxConcurrentInstances
One-way
• [OperationContract(IsOneWay =true)]
– Przed metodą usługi
– Domyślnie – false
– Metoda musi zwracad void (inaczej błąd)
• Wyjątki usługi nie dotrą do klienta
• Błędy komunikacyjne nadal się pojawiają
• Jeśli reliablesession (transport session) – wtedy jest
przerywana
• Najlepsza praktyka: tylko PerCall i Singleton
59.
Operacje duplex
• Niektórebindingi
– WSDualHttpBinding, NetTcpBinding, NetNamedPipeBinding
– Nie jest standardem
• Odpowiedź wywoływana przez serwis na klasie klienta
– WSDualHttpBinfing - domyślnie port 80 (możliwa zmiana)
• Wywołanie natychmiastowe lub referencja na poźniej
IMyContractCallback callback =
OperationContext.Current.GetCallbackChannel<IMyContractCallback>( );
interface ISomeCallbackContract
{
[OperationContract]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
interface IMyContract
{
[OperationContract]
void DoSomething();
}
60.
Po stronie klienta
classMyCallback : IMyContractCallback
{
public void OnCallback( )
{ ... }
}
IMyContractCallback callback = new MyCallback();
InstanceContext context = new InstanceContext(callback);
MyContractClient proxy = new MyContractClient(context) ;
proxy.DoSomething();
61.
Callback
• Wywoływanie callbackuw operacji usługi
– Domyślnie 1 wątek ma dostęp do metod
– W trakcie wywoływanej operacji lock na instancję
kontekstu
– Po wywołaniu callback – odpowiedź do serwera na
ten sam (zablokowany) kanał
• ConcurrencyMode
– Single
– Multiple – ok, kłopoty z synchronizacją
– Reentrant – ok
• Lub: metody OneWay (brak odpowiedzi)
62.
Streaming
• Klasyczne wywołania– buforowane po stronie
serwera
– Blokowanie do czasu zakooczenia przesyłania
komunikatu
• Streaming (wyłącznie klasa Stream)
– Niektóre bindingi (TCP, IPC, Basic HTTP)
– Niemożliwy do wykorzystania z message-level
security
<bindings>
<basicHttpBinding>
<binding name = "StreamedHTTP"
transferMode = "Streamed„
maxReceivedMessageSize = "120000"/>
</basicHttpBinding>
</bindings>
Podstawy
• Błędy komunikacyjnei kanałów
• Błędy po stronie serwisu
– Izolacja błędów od klienta!
• Jeśli jest sesja – automatycznie stan kanału
CommunicationState.Faulted
// w klasycznym .NET ok – tu CommunicationObjectFaultedException
// uwaga na using!- po dispose nowa instancja proxy
IMyContract obj = new MyClass( );
try
{
obj.MyMethod( );
}
catch
{}
obj.MyMethod( );
66.
Propagacja błędów
• Ustandaryzowane– SOAP fault
• FaultException<T>
class Calculator : ICalculator
{
public double Divide(double number1, double number2)
{
if (number2 == 0)
{
DivideByZeroException exception = new DivideByZeroException();
throw new FaultException<DivideByZeroException>(exception);
}
return number1 / number2;
}
}
67.
Kontrakty błędów
• Każdybłąd dociera do klienta jako FaultException
– Także FaultException<T> (dziedziczy po FaultException)
– Wszystko co jest wymieniane musi byd w kontrakcie
• [FaultContract]
– Musi byd dokładnie klasa błędu
– Nie może byd to nawet klasa dziedzicząca!
– Może byd kilka – dla kilku typów
– Nie można aplikowad dla operacji OneWay (błąd)
– Nie zamyka kanału komunikacji (każdy dziedziczący po FaultException)
• Kontrakt publikowany w metadanych
– Klasy błędów importowane podczas generacji proxy
• IErrorHandler
[OperationContract]
[FaultContract(typeof(DivideByZeroException))]
double Divide(double number1, double number2) { ... }
// jeśli typeof(Exception) -może być tylko throw Exception!
68.
Debugowanie - ExceptionDetail
[ServiceBehavior(IncludeExceptionDetailInFaults= true)]
class MyService : IMyContract
{
public void MethodWithError()
{
throw new InvalidOperationException("Some error");
}
}
// ---------------------------------------
MyContractClient proxy = new MyContractClient( );
try
{
proxy.MethodWithError( );
}
catch(FaultException<ExceptionDetail> exception)
{
Debug.Assert(exception.Detail.Type ==
typeof(InvalidOperationException).ToString( ));
Debug.Assert(exception.Message == "Some error") ;
}
// Może byd ustawiane ręcznie / w konfiguracji hosta (debugowanie istniejącego serwisu!)
// Uwaga przy deployment!
Transaction Manager
• Nadzorujetransakcję
• Lightweight Transaction Manager (LTM)
– AppDomain, SQL 2005/2008
• Kernel Transaction Manager (KTM)
– Vista / Windows Server 2008
– KRM: Transactional file system (TxF), Transaction registry (TxR)
– Tylko jeden serwis
• Distributed Transaction Coordinator (DTC)
– Wykorzystywany w transakcjach rozproszonych
– OleTX / WSAT
• Każda transakcja najpierw zarządzana przez LTM
– Jeśli więcej usług / zasobów – promocja do DTC
– Jeśli zasób KRM – promocja do KTM
Głosowanie (kod)
• Zatwierdzeniepowinno byd ostatnim wywołaniem w
metodzie
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = false) ]
public void MyMethod( )
{
try
{
/* Na koniec: */
OperationContext.Current.SetTransactionComplete( );
}
catch
{
/* np. logowanie, następnie: */
throw;
}
}
79.
Izolacja transakcji
• Domyślnie– Unspecified
– Wykorzystywany poziom transakcji klienta
• Jeśli inny – klient musi mied zadeklarowany
poziom transakcji taki sam (inaczej błąd)
class MyService : IMyContract
{ ... }
[ServiceBehavior(TransactionIsolationLevel =
IsolationLevel.Unspecified)]
class MyService : IMyContract
{ ... }
80.
Klient
using (TransactionScope scope= new TransactionScope())
{
MyContractClient proxy1 = new MyContractClient( );
proxy1.MyMethod( );
proxy1.Close( );
MyOtherContractClient proxy2 = new MyOtherContractClient( );
proxy2.MyOtherMethod( );
proxy2.Close( );
scope.Complete( );
}
PerSession – c.d.
•Możliwe zrównanie czasu trwania sesji z czasem
trwania transakcji
– ReleaseServiceInstanceOnTransactionComplete = false
– TransactionAutoComplete = false
– Uwaga na timeout
• Nie zalecane
[ ServiceBehavior(TransactionAutoCompleteOnSessionClose = true) ]
class MyService : IMyContract {. . . }
85.
Durable Services
• Stanzapisywany w bazie
– Transakcja może niechcący przed tym
powstrzymad
• Domyślnie – zapisywanie stanu nie jest
częścią transakcji
• [SaveStateInOperationTransaction]
– Domyślnie – false
– True – aby stan był zarządzany transakcją
86.
Singleton
• Domyślnie –PerCall
– ReleaseServiceInstanceOnTransactionComplete
• Stan w Volatile Resource Managers
Tryby
• [ServiceBehavior(ConcurrencyMode=…)+
– Single
–Reentrant
– Multiple
• Single
– Domyślny
– Tylko jeden wątek na raz
• Multiple
– Konieczne synchronizowanie dostępu
• lock { }
• [MethodImpl(MethodImplOptions.Synchronized)]
• W takim wypadku – niewielki zysk
– Limitowane przez throttle – domyślnie 16 połączeo
• Reentrant
89.
Wątek UI
• WPF,Silverlight – Dispatcher
partial class MyForm : Form
{
Label m_CounterLabel;
public SynchronizationContext MySynchronizationContext
{ get; set; }
public MyForm()
{
InitializeComponent();
MySynchronizationContext = SynchronizationContext.Current;
}
void InitializeComponent()
{
. . .
m_CounterLabel = new Label( );
. . .
}
public int Counter
{
get
{
return Convert.ToInt32(m_CounterLabel.Text);
}
set
{
m_CounterLabel.Text = value.ToString();
}
}
}
90.
Synchronization Context –c.d.
[ServiceContract]
interface IFormManager
{
[OperationContract]
void IncrementLabel();
}
class MyService : IFormManager
{
public void IncrementLabel()
{
MyForm form = Application.OpenForms[0] as MyForm;
Debug. Assert(form ! = null) ;
SendOrPostCallback callback = delegate
{
form.Counter++;
};
form.MySynchronizationContext.Send(callback, null);
}
}
static class Program
{
static void Main()
{
ServiceHost host = new ServiceHost(typeof(MyService));
host.Open();
Application.Run(new MyForm());
host.Close();
}
}
91.
Wątek UI
[ServiceBehavior(UseSynchronizationContext =true)]
class MyService : IMyContract {. . . }
• Jeśli wątek uruchamiający usługę ma Synchronization
Context, automatycznie kontekst przechodzi do usługi
• Form jako usługa (i tak ścisłe powiązanie)
– Form jako callback – ok
• Inne rozszerzenia
– Np. Ustawianie priorytetów dla wywołao
http://msdn.microsoft.com/en-us/magazine/cc163321.aspx
92.
Operacje asynchroniczne
• Specjalnepole checkbox podczas dodawania
referencji
• Klasycznie jak w .NET
– Begin<operacja>, End<operacja>
– End – blokuje
– Callback
– Polling – IsCompleted
– Wiele wywołao – WaitAll() i
IAsyncResult.WaitHandle
Serwisy kolejkowane
• Dostępnośdusługi
• Load leveling – skolejkowanie „piku”
• Kolejkowanie niezależnych operacji
biznesowych
• Kompensacja (druga kolejka z wynikami)
• Kolejkowanie w WCF
– NetMsmqBinding
– Opakowanie komunikatu SOAP w komunikat
MSMQ
95.
Architektura
• Klient wywołujeproxy
• Proxy zapisuje komunikat do kolejki
• Usługa netMsmqBinding instaluje Channel Listener
• Channel listener powiadamia o komunikacie –
komunikat zdejmowany i przetwarzany
96.
Kolejkowanie w WCF
•Tylko operacje OneWay
– Nie mogą zwracad wartości
– Nie mogą zwracad błędów
• Kolejki MSMQ
– Public – pomiędzy serwerami w domenie
– Private – lokalne, nie wymagają DC
– Jeden endpoint = jedna kolejka
• Hosting WAS – nazwa kolejki = nazwa pliku svc
– address = "net. msmq: //localhost/private/WASService. svc"
<endpoint
address = "net.msmq: //localhost/private/MyServiceQueue"
binding = "netMsmqBinding"
... />
97.
Transakcje
• MSMQ uczestniczyw transakcjach (opcja)
– Jeśli włączone – komunikaty zapisywane na dysk
– Transakcje playback – nasz kod
• Publiczna kolejka i reliable messeging
– Kolejka proxy
– Automatyczne ponawianie wysłania komunikatu
98.
Sesja i MSMQ
•SessionMode.Allowed lub
SessionMode.NotAllowed – brak sesji
– Każdy komunikat pojedynczo
• SessionMode.Required
– Sessiongram – pakowanie komunikatów w
„paczkę”
– Zachowana kolejnośd doręczenia
99.
Instancjonowanie PerCall
//Klient
using(TransactionScope scope= new TransactionScope( ))
{
MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( ); //Komunikat wysłany
proxy.MyMethod( ); //Komunikat wysłany
proxy.Close( );
scope.Complete( );
} // Zatwierdzane
• Brak przejścia transakcji na stronę usługi
• Każde wywołanie osobno, osobne instancje
100.
Instancjonowanie PerSession
using(TransactionScope scope= new TransactionScope( ))
{
MyContractClient proxy = new MyContractClient( );
proxy.MyMethod();
proxy.MyMethod();
proxy.Close( ); //Skomponowano komunikat, zapis.
scope.Complete( ); //Musi być za proxy.Close!!
} //Pojedynczy komunikat zapisany
101.
Instancjonowanie PerSession
• Niemogą mied trwającej sesji
– Podobnie do PerCall
• Ale - wszystkie komunikaty do tej samej
instancji
102.
Throttling
• Po włączeniuusługi – wszystkie komunikaty
na raz
– Duża liczba instancji kontekstu – obciążenie
• Umożliwia stopniowe przetwarzanie
103.
Kiedy pojawią sięproblemy
• Błędy
– Komunikacja
– Bezpieczeostwo
– Quota
– …
• Dead-letter queue (DLQ)
– Problem z doręczeniem
– Nieudany commit transakcji playback
– Przetwarzanie kolejki jak zwykły serwis (kontrakt musi byd
ten sam / dziedziczący)
Komunikaty Poison
• KomunikatyPoison
– Nieustanne próby doręczenia
– Zawsze błąd
– Również usługa z polimorficznym kontraktem
• Możliwe akcje
– Drop – odrzucenie i potwierdzenie, że dostarczono
– Reject – odrzucenie i NACK
– Move – przeniesienie do odpowiedniej kolejki
107.
Popularne wzorce
• Responseservice
– Komunikaty mogą byd jednokierunkowe
– Można zapisywad odpowiedzi w innej kolejce
• HTTP Bridge
– Kolejki – raczej intranet
– Nie interoperacyjne
– Mostek WS-HTTP
Tryby
• Transport
– Negocjacja(protokół), zależy od protokołu
– Weryfikacja integralności treści komunikatu
– Akcelerowane przez karty sieciowe
• Message
– Treśd komunikatu szyfrowana
• Mieszane
– Mix - transport do integralności i szyfrowanie
hasła
– Oba – uwaga na wydajnośd
Uwierzytelnienie
// Hasło (klasycznie)
MyContractClientproxy = new MyContractClient( );
proxy.ClientCredentials.UserName.UserName = "MyUsername";
proxy.ClientCredentials.UserName.Password = "MyPassword";
proxy.MyMethod( );
proxy.Close( );
// Windows (raczej nie stosowane w Internet, chociaż możliwe)
<behavior name = "UsernameWindows">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode = "Windows"/>
<serviceCertificate
. . .
/>
</serviceCredentials>
</behavior>
115.
Autoryzacja
• Najprościej –Role Provider
– Model znany z ASP.NET
– Dowolne źródło danych (własna lub generowana
baza)
• Duplex
– Odradzane, w prosty sposób autoryzacja
niedostępna
116.
B2B
• Nie współdzieląkont
– Przedstawianie się certyfikatem X509 (klient)
– Dozwoleni klienci instalowani w Trusted People
• Szyfrowanie certyfikatem serwera
• Najczęściej nie potrzebna autoryzacja
– Niewielka liczba lub jeden klient
– Możliwe wykorzystanie Role Providera –
identyfikator certyfikatu jako username
Terminologia
• RSS –prosty format XML dla zestawu danych
• ATOM – jak RSS, ale bardziej ustrukturalizowany
• Syndykacja (Syndication) – nadzbiór RSS, ATOM, inne
• AJAX – DHTML + JavaScript + asynchroniczne
przetwarzanie
• JSON – Format danych (tablicy) w JavaScript
• REST – …
• POX – plain old XML (bez koperty SOAP)
120.
REST
• Protokół HTTPzostał zaprojektowany z 8 słowami
• Low REST – API bazujące na GET & POST
– Też tak działa przeglądarka
• High REST sugeruje stosowanie 4 głównych słow
– GET/PUT/DELETE/POST
– CRUD dla Web
• Wywoływanie usługi bez warstwy „komunikatu” czy „koperty”
– …sam HTTP
• Oparte na
– URI do definowania endpoint (zasób)
• Spacje & URITemplates
– Polecenia HTTP definiują operacje
• GET/PUT/DELETE/POST
– Typy zawartości
• XML , JSON, <mikroformaty>
121.
Aplikacje REST -atrybuty
• WebGet: Atrybut do oznaczania operacji które są
wołane przez HTTP GET
• webHttpBinding: Binding dla usług REST
• webServiceHost: Klasa do hostowania usług REST
• webServiceHostFactory: Klasa do hostowania usług
REST które nie wymagają pliku konfiguracyjnego
[OperationContract]
[WebGet(UriTemplate=“/WeatherMap/{country}/{zipcode}”)]
Stream GetWeatherMap(String country, String zipcode);
122.
Developing REST Applications
WCF& URI Spaces: URITemplate
• QueryString syntax still available
• URITemplate: formalism for binding URI structure to
method parameters
[OperationContract]
[WebGet(UriTemplate=“/WeatherMap/{country}/{zipcode}”)]
Stream GetWeatherMap(String country, String zipcode);
http://myserver/WeatherMap/USA/98052
http://myserver/GetWeatherMap?country=USA&zipcode=98052
123.
Developing REST Applications
WCF& Transfer: HTTP verbs support
• WebInvoke: new attribute for making a method accept
any non-GET verb
– PUT, DELETE, POST...
[OperationContract]
[WebInvoke(METHOD=“PUT”)]
WeatherReport UploadWeatherReport(WeatherReport theReport);
124.
Ręczne modelowanie URI
•Pomoc: System.UriTemplate
Uri address = new Uri(“http://localhost:2000”);
UriTemplate template =
new UriTemplate(“{artist}/{album}”);
Uri boundUri =
template.BindByPosition(address,
“Northwind”, “Overdone”);
UriTemplateMatch match = template.Match(address,
boundUri);
String bandName = match.BoundVariables[“artist”];
125.
URI w kontrakcieWCF
• Składnia QueryString nadal dostępna
• Typ UriTemplate mapuje na parametry
– Jako atrybut albo jako oddzielny typ
[OperationContract]
[WebGet(UriTemplate=“/Image/{bandName}/{album}”)]
Stream GetAlbumImage(String bandName, String album);
[OperationContract]
[WebGet(UriTemplate=“/Image?name={bandName})]
Stream GetMainImage(String bandName);
126.
Kontrakt typu zobacz/ zrób
[OperationContract]
[WebGet(UriTemplate=“/Image/{bandName}/{album}”)]
Stream GetAlbumImage(String bandName, String album);
[OperationContract]
[WebInvoke(METHOD=“PUT”)] // {PUT, POST, DELETE}
void AddAlbum(AlbumInfo albumInfo);
127.
REST – zwracaniewartości
• Typ zawartości zależy od:
– Zachowanie enableWebScript (JSON) albo ustawione w
klasie hostującej
– Atrybutu Response.Format
– Ręcznie:
• WebOperationContext.Current.OutgoingResponse.Conte
ntType
[OperationContract]
[WebGet(UriTemplate =
"WeatherReport/{country}/{zipcode}/JSON",
ResponseFormat=WebMessageFormat.Json)]
WeatherReport GetWeatherReportWithTemplateJSON(string
country, string zipcode);
128.
JSON – coto jest?
• JavaScript Object Notation
• Format do łączenia JavaScript i obiektów
– Łatwiejsze niż XML
• Użycie
– ASP.NET AJAX
– Skrypty JS
– Dynamiczny kod…
var data = {“temp” : 59, “descr” : “cloudy”};
document.write (“The weather is “ + data.descr);
129.
Konwencje związane zdanymi
[OperationContract(Name=“TestOp”)]
[WebInvoke(METHOD=“PUT”)] // {PUT, POST, DELETE}
String[] AddAlbum(AlbumInfo albumInfo);
PUT /albumservice/AddAlbum HTTP 1.1
HOST: contoso.com
<albumInfo>
<Name>Hysteria</Name>
<RelDate>8/3/1987</RelDate>
...
</albumInfo>
•XML Namespace
pochodzi z kontraktu
•Nazwy parametrów z
sygnatury operacji
WCF i syndykacja
Syndykacja:Gromadzenie danych z różnych źródeł w
jednym miejscu (blogi, artykuły itp.)
SyndicationFeed: pojęcie „feedu” niezależne od
formatu
SyndicationFeedFormatter<>
[ServiceKnownType(typeof(Atom10FeedFormatter))]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
[ServiceContract]
interface IPictureSyndication {
[OperationContract]
[WebGet(UriTemplate=“Images/{format}")]
SyndicationFeedFormatter<SyndicationFeed>
GetImage(String format);
}
132.
Kontekst bez protokołuWS=*
• Konwersacja bazująca na kanale komunikacyjnym -
problem
• Konwencja wywołania
– W tle
• Binding:
basicHttpContextBinding
NetTcpContextBinding
BasicHttpContextBinding
• Behavior:
– <persistenceProvider>
• Ten sam co w WF
• Uwaga! Klient musi też byd świadomy kontekstu
– WCF Service Host nie jest…