Ten artykuł pochodzi z serii przygotowań do egzaminu 70-503: Windows Communication Foundation.
Wiemy już jak wystawić światu naszą usługę. Najczęściej skorzystamy z jakiegoś standardu i to nam wystarczy. Czasem jednak potrzeba coś dopasować do naszych potrzeb.
Dostosowywanie standardowych bindowań
Każdy ze standardowych sposobów komunikacji (ang. bindings) ma kilka właściwości, które możemy dowolnie zmieniać. Np. wsHttpBinding ma następujące właściwości:
- AllowCookies – czy klient akceptuje i tworzy ciasteczka (ang. Cookies), domyślnie False,
- BypassProxyOnLocal – czy używać proxy dla lokalnego adresu, domyślnie False,
- CloseTimeout – ilość czasu jaką należy odczekać przy zamykaniu połączenia zanim zostanie wyrzucony wyjątek, domyślnie 1 minuta
- HostNameComparisonMode – w jaki sposób nazwa hosta jest używana do dostępu do serwisu, domyślnie StrongWildcard,
- MaxBufferPoolSize – maksymalny zakres pamięci dla buffer manager’a, domyślnie 65536 bajtów,
- MaxRecievedMessageSize – maksymalny rozmiar odbieranej wiadomości, domyślnie 65536 bajtów,
- MessageEncoding – kodowanie wiadomości MTOM lub Text/XML, domyślnie Text,
- Name – nazwa bindowania, domyślnie Null,
- Namespace – przestrzeń nazw XML, domyślnie http://tempuri.org/,
- OpenTimeout – ilość czasu na otwarcie połączenia, domyślnie 1 minuta,
- ProxyAddress – adres proxy, ignorowany gdy UseDefaultWebProxy jest ustawione na True, domyślnie Null,
- ReaderQuotas – ograniczenia dla zawartości wiadomości, domyślnie None,
- ReceiveTimeout – jak długo połączenie może być nieaktywne, domyślnie 10 minut,
- SendTimeout – ilość czasu na wysyłanie wiadomości, domyślnie 1 minuta,
- TextEncoding – kodowanie tekstu wiadomości, domyślnie UTF8Encoding,
- TransactionFlow – czy wspierać transakcje, domyślnie False,
- UseDefaultWebProxy – czy używać domyślnego proxy HTTP, domyślnie True.
Informacje o parametrach pozostałych bindowań znajdziemy w dokumentacji MSDN.
Teraz trochę kodu. Ustawianie parametrów w pliku App.config wygląda następująco (w linii 13 jest ustawiona właściwość CloseTimeout na 3 minuty):
1: <system.serviceModel>
2: <services>
3: <service name="OrderService">
4: <endpoint address=""
5: contract="MyNamespace.IOrderService"
6: binding="WsHttpBinding"
7: bindingConfiguration="CloseTimeout">
8: </endpoint>
9: </service>
10: </services>
11: <bindings>
12: <wsHttpBinding>
13: <binding name="CloseTimeout" closeTimeout="00:03:00">
14: </binding>
15: </wsHttpBinding>
16: </bindings>
17: </system.serviceModel>
To samo możemy zrobić z poziomu C#:
1: ServiceHost host = new ServiceHost(typeof(OrderService));
2: WSHttpBinding wsBinding = new WSHttpBinding();
3: TimeSpan ts = new TimeSpan(00, 03, 00);
4: wsBinding.CloseTimeout = ts;
5: host.AddServiceEndpoint(
6: typeof(MyNamespace.IOrderService),
7: wsBinding,
8: "http://localhost:8000/OrderService/");
Własne bindowania
Jeśli nie wystarczy nam zmodyfikowanie właściwości któregoś ze standardowych bindowań, zawsze możemy utworzyć własną klasę obsługującą komunikację (musi one dziedziczyć po CustomBinding). Binding składa się z elementów kontrolujących poszczególne elementy: protokół, kodowanie, itp. Najważniejsze jest by poszczególne elementy były dodawane w odpowiedniej kolejności:
- Transaction flow – obsługa transakcji,
- Reliability – obsługa kanałów transmisji, umożliwia zachowanie kolejności wiadomości, ten element dostępny jest dla netTcpBinding, wsHttpBinding i wsDualHttpBinding,
- Security – obsługa autoryzacji, autentykacji, zabezpieczeń itp.
- Transport – specyfikacja transportu: właśna lub któraś z następujących: TCP, NamedPipes, HTTP, HTTPS, MSMQ lub Peer-to-Peer,
- Encoding – obsługa kodowania wiadomości jako tekst, binarnie lub MTOM,
Ostatnie dwa elementy (Transport, Encoding) są wymagane, a pozostałe są opcjonalne. Tak jak wcześniej, możemy definiować bindowania w pliku App.config lub w kodzie C#:
1: <system.serviceModel>
2: <services>
3: <service name="OrderService">
4: <endpoint address="http://localhost:8000/OrderService/"
5: contract="MyNamespace.IOrderService"
6: binding="customBinding"
7: bindingConfiguration="NewBinding">
8: </endpoint>
9: </service>
10: </services>
11: <bindings>
12: <customBinding>
13: <binding name="NewBinding">
14: <reliableSession />
15: <security>
16: <localServiceSettings inactivityTimeout="00:10:10"/>
17: </security>
18: <httpTransport/>
19: <textMessageEncoding />
20: </binding>
21: </customBinding>
22: </bindings>
23: </system.serviceModel>
1: ServiceHost host = new ServiceHost(typeof(MyNamespace.OrderService));
2: BindingElementCollection bec = new BindingElementCollection();
3:
4: SymmetricSecurityBindingElement ssbe = new
5: SymmetricSecurityBindingElement();
6: ssbe.LocalServiceSettings.InactivityTimeout = new TimeSpan(0, 10, 0);
7: bec.Add(ssbe);
8: bec.Add(new TextMessageEncodingBindingElement());
9: bec.Add(new HttpsTransportBindingElement());
10:
11: CustomBinding customBinding = new CustomBinding(bec);
12:
13: host.AddServiceEndpoint(
14: typeof(MyNamespace.IOrderService),
15: customBinding,
16: "http://localhost:8000/OrderService/");
Na dzisiaj tyle, z następnych lekcji dowiemy się jak uruchomić usługę na serwerze IIS lub w aplikacji konsolowej.