Claudio Masieri

SOA, Windows Communication Foundation (WCF), ASP.NET e le Architetture Distribuite

febbraio 2007 - Posts

WS-Discovery e WCF

WS-Discovery è un protocollo WS-* compatibile che permette di utilizzare un servizio, senza specificarne l'indirizzo e il tipo di trasporto.
Di recente ho dovuto implementarlo con WCF e ho pensato di riportare su questo blog le principali problematiche.

Innanzitutto WS-Discovery, al contrario di WCF, si basa sul contratto e non sulla terna ABC del mondo WCF. Infatti il contratto è l'unico parametro necessario per la ricerca del servizio. Binding e Address saranno determinati dopo la fase di discovery.

La cosa che mi sarebbe piaciuto fare è un DiscoveryBindingElement che utilizzato da configurazione permettesse di definire il solo contratto. Questo aspetto  non è un cambiamento da poco dal punto di vista della configurazione di WCF e ho dovuto abbandonare questa strada in quanto l'ho trovata non percorribile.

<system.serviceModel>
   <
extensions>
      <
bindingExtensions>
          <
add name="discoveryBinding" type="WSDiscovery.Configuration.DiscoverySection, WS-Discovery, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </
bindingExtensions>
  </
extensions>
<
client>
   <
endpoint address="discovery://239.255.255.250:3702" binding="discoveryBinding" bindingConfiguration="discovery" contract="SampleInterface.IBorsa" name="DiscoveryBinding.Proxy" />
 </
client>
 <
bindings>
   <
discoveryBinding>
       <
binding name="discovery">
          <
discoveryBinding>
               <
scopes mathcBy="http://schemas.xmlsoap.org/ws/2004/10/discovery/rfc2396">
            <
scope>http://mieiscopes.org/urlmioscope</scope>
           </
scopes>
         </
discoveryBinding>
       </
binding>
     </
discoveryBinding>
   </
bindings>
</
system.serviceModel>

L'alternativa è un proxy che utilizza WS-Discovery implementato tramite una classe astratta, ma anche concreta, del tipo DiscoveryClientBase<TChannel> che ha un costruttore con parametro e un costruttore con un array di scopes (uri che specificano parametri aggiuntivi utili per la scelta del servizio a parità di contratto). 

Un componente di infrastruttura deve essere assolutamente trasparente. Sulle orme della classe ClientBase di WCF ho utilizzato un sistema a proxy dinamici per esporre una proprietà Channel del tipo <TChannel> che permette in modo analogo alla classe ClientBase dirigere tutte le chiamate ai metodi dell'interfaccia ad una funzione "asso piglia tutto" che imbusta fisicamente il messaggio soap e lo invia. Una buona descrizione del metodo dei proxy dinamici è disponibile qui.

Le cose da tenere conto lato client sono due:

  1. Ogni entry recuperata dal campo va memorizzata in una global storage con tutti i contratti recuperati o pervenuti dal campo (grazie ai messaggi di Hello)
  2. Se dovesse comparire un DiscoveryProxy i meccanismi di trasporto cambiano completamente (unicast->multicast e viceversa) e quindi bisogna essere pronti all'evenienza

Il client ha funzioni analoghe quando lavora con la presenza di un discovery proxy e quando questo non è presente: utilizzare uno State (Gof) con una classe astratta che tiene le funzioni comuni e due classi concrete, DiscoveryProxyState e DiscoveryNoProxyState, agevola parecchio il lavoro.

Una funzione interessante che ho aggiunto nel client è che memorizzando le risposte dal campo è in grado di fornire piu servizi che implementano un contratto. La scelta del contratto da utilizzare è realizzata tramite un componente di riordino, che utilizzando logica di processo esegue il suo lavoro. Nel momento in cui invio un messaggio al servizio e dovessi avere un Fault nella comunicazione la classe proxy automagicamente prova ad usare un'altro servizio presente in lista cancellando quello irraggiungibile. Una funzione banale ma di ottima efficacia e totale trasparenza per l'utilizzatore, avendo tutto mascherato attraverso il dynamic proxy.

Dedicherò un successivo post per esprimere le mie considerazioni per il lavoro fatto lato servizio.

Posted: feb 10 2007, 10.20 by claudiom | with no comments
Filed under: