Druga część mojej sobotniej prezentacji dotyczyła nowości w Windows Communication Foundation. Aby zmieścić się w założonych piętnastu minutach, spośród wielu ciekawostek o których można poczytać np. u Nicholasa Allena, wybrałem dwie:

  • RoutingService
  • WS-Discovery

Dlaczego akurat te dwie? Otóż dlatego, że udało mi się wymyślić jeden wspólny temat, pod szyldem którego mógłbym je prezentować — usługę Event Brokera. Jeśli ktoś nie kojarzy tego wzorca, Event Broker to pośrednik, który forwarduje informacje o zdarzeniach pochodzące od nadawcy (źródła) do dowolnej liczby odbiorców. Celem tego wzorca jest zmniejszenie powiązania miedzy nadawcą i odbiorcami.

Projekt

Poniższa prezentacja (6 slajdów) pokazuje sposób działania Event Brokera. Pozostaje jedynie mapowanie poszczególnych funkcji na dostępne technologie. Dzięki nowemu WCF, wszystko czego potrzebujemy znajduje się już na naszym komputerze.

Funkcjonalność rejestracji subskrybentów (otrzymujących komunikaty) w Event Brokerze zapewnia nam obsługa WS-Discovery. Filtrowanie i routowanie przychodzących komunikatów do zainteresowanych odbiorców to funkcje nowego, wbudowanego w WCF, RoutingService’u. Wszystko, co musimy zrobić własnoręcznie to sprzęgnąć te dwie technologie tak, aby reakcja na ogłoszenia WS-Discovery powodowała odpowiednią modyfikację tablicy routingu.

Routing

RoutingService to gotowa do użycia usługa dostarczana wraz z nowym WCF.  Jej użycie wymaga trzech prostych kroków: stworzenia nowego hosta, skonfigurowania rodzaju routingu oraz podpięcia odpowiedniego zachowania. W kodzie wygląda to tak:

var routerServiceHost = new ServiceHost(typeof (RoutingService));
routerServiceHost.AddServiceEndpoint(typeof (ISimplexDatagramRouter), new BasicHttpBinding(), RouterAddress);
routerServiceHost.Description.Behaviors.Add(new RoutingBehavior(subscriptionManager.RoutingConfiguration));

Konfiguracja rodzaju routingu polega na utworzeniu endpoint’u odpowiedniego typu. Ja wykorzytsałem ISimplexDatagramRouter ponieważ potrzebuje przekazywać pakiety w jednym kierunku. Możliwy jest jednak także routing komunikacji request-response (z tym, że raczej już bez multicast’u).

Do konstruktora RoutingBehavior przekazujemy obiekt RoutingConfiguration, który m.in. zawiera tablicę routingu. Tablica ta może być modyfikowana z zewnątrz w dowolnym momencie, a dokonane zmiany zostaną uwzględnione podczas routowania następnego komunikatu. Kod modyfikujący tablicę wygląda np. tak:

var contract = ContractDescription.GetContract(typeof (ISimplexDatagramRouter));
var subscriber = new ServiceEndpoint(contract, new BasicHttpBinding(), address);
RoutingConfiguration.FilterTable.Add(new ActionMessageFilter(actions), new List<ServiceEndpoint> {subscriber});

WS-Discovery

Mój Event Broker wykorzystuje protokół WS-Discovery poprzez nasłuchiwanie na ogłoszenia (announcements) o pojawieniu się lub zniknięciu usług. Aby dla danej usługi WCF włączyć wysyłanie tych ogłoszeń, wystarczy zmodyfikować jej konfiguracje według poniższego wzorca:

<services>
  <service behaviorConfiguration="discoveryBehavior"
            name="Subscriber.SayHelloService">
    <endpoint name="udpDiscoveryEpt" kind="udpDiscoveryEndpoint" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="discoveryBehavior">
      <serviceMetadata/>
      <serviceDiscovery>
        <announcementEndpoints>
          <endpoint kind="udpAnnouncementEndpoint" />
        </announcementEndpoints>
      </serviceDiscovery>
    </behavior>
  </serviceBehaviors>
</behaviors>

Konieczne jest dodanie nowego endpointu oraz dodanie do usługi odpowiedniego zachowania. W kodzie nie są potrzebne żadne zmiany. Modyfikacja ta sprawi, że subskrybenci będą wysyłać ogłoszenie w momencie przejścia w tryb on-line. Kolejnym krokiem jest dodanie do Event Brokera kodu, który będzie nasłuchiwał na te ogłoszenia i, zgodnie z ich treścią, modyfikował tablicę routingu. Funkcjonalność tą realizuje poniższy fragment:

var subscriptionListener = new SubscriptionListener(subscriptionManager);
var announcementService = new AnnouncementService();

announcementService.OnlineAnnouncementReceived += (s, a) => subscriptionListener.Subscribe(a);
announcementService.OfflineAnnouncementReceived += (s, a) => subscriptionListener.Unsubscribe(a);

var announcementServiceHost = new ServiceHost(announcementService);
announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());

Jak widać, usługa WS-Discovery oferuje dwa eventy, pod które możemy podpiąć się z własnym kodem. Jest to bardzo wygodny sposób pracy.

Podsumowanie

Zapraszam do ściągnięcia całego przykładu z galerii MSDN. Mam nadzieję, że powyższy post pozwoli Wam łatwiej zrozumieć kod. Specjalnie nie omawiałem klasy obsługującej parsowanie WSDL-a, która jest niezbędna w ostatecznym rozwiązaniu, jednak nie jest ważna z punktu widzenia funkcjonalności Event Brokera. WCF 4 — polecam każdemu!

VN:F [1.8.7_1070]
Rating: 0.0/5 (0 votes cast)