Hello World en Windows Communication Foundation

Hay multitud de este tipo de ejemplos en la web, pero quería comentar un ejemplo en Visual Basic .NET, y sin usar archivos de configuración, para ir explicando y entendiendo, algunos conceptos de Windows Communication Foundation. El código del proyecto se puede bajar de WCFHelloWorld1.zip.

Recursos, explicaciones en inglés, ejemplos y el propio .NET 3.0 están disponibles desde:

http://wcf.netfx3.com/

http://www.netfx3.com/

 

La solución de este “post” de ejemplo consta de tres proyectos:

Todos los proyectos referencian a una nueva DLL .NET que contiene la implementación de System.ServiceModel:

Hay un proyecto consola de cliente, y otro proyecto consola con el servidor. El tercer proyecto, es una librería que define el contrato:

1 Imports System 2 Imports System.ServiceModel 3 Imports System.Runtime.Serialization 4 5 <ServiceContract()> _ 6 Public Interface IHelloWorld 7 <OperationContract()> _ 8 Function HelloWorld(ByVal name As String) As String 9 End Interface 10 11

Vemos que el contrato es una interfaz, y está adornada con el atributo ServiceContract. Cada operación de la interfaz que queremos exponer dentro del servicio WCF, deberá tener el atributo OperationContract.

El programa cliente referencia a esta librería, y por eso, conoce esta interfaz (en otros ejemplos, el cliente puede agregar una referencia a un servicio, y el generador de código del proxy cliente, construye la interfaz, pero en este ejemplo quería ir armando la relación programáticamente).

El programa servidor tiene una implementación, una clase que implementa la interfaz de servicio:

1 Imports WCFHelloWorldLibrary 2 3 Public Class HelloWorldService 4 Implements IHelloWorld 5 6 Public Function HelloWorld(ByVal name As String) As String Implements WCFHelloWorldLibrary.IHelloWorld.HelloWorld 7 Return "Hello " & name 8 End Function 9 End Class 10

 

El programa servidor, un programa de consola:

 

1 Imports System 2 Imports System.ServiceModel 3 4 Imports WCFHelloWorldLibrary 5 6 Module HelloWorldHost 7 8 Sub Main() 9 Dim host As ServiceHost = Nothing 10 ' Consider putting the baseAddress in the configuration system 11 ' and getting it here with AppSettings 12 Dim baseAddress As Uri = New Uri("http://localhost:8080/WCFHelloWorldHost") 13 14 ' Instantiate a new ServiceHOst 15 host = New ServiceHost(GetType(HelloWorldService), baseAddress) 16 Dim binding As New BasicHttpBinding() 17 18 host.AddServiceEndpoint(GetType(IHelloWorld), binding, "/HelloWorld") 19 20 host.Open() 21 22 Console.WriteLine("Press enter to end") 23 Console.ReadLine() 24 25 host.Close() 26 End Sub 27 28 End Module 29

El tipo ServiceHost es parte de System.ServiceModel, lo nuevo de .NET 3.0 que implementa Windows Communication Foundation. Es la clase que permite exponer una implementación de un servicio, en este caso, objetos del tipo HelloWorldService.

En el constructor del ServiceHost se puso el tipo que albergará, y la dirección donde se expondrá. Ahora bien, un servidor puede exponer la misma implementación, en distintos service endpoints. Cada service endpoint puede indicar lo que se llama un binding, y un nombre. Eso se agregó en la línea 18. En la línea 16 se definió que el binding será basado en HTTP básico (hay bindings más poderosos en WCF, como uno que implementa las últimas definiciones de la especificación de servicios web, puede probar también WSHttpBinding, WSDualHttpBinding, y aparecerán más en la historia de WCF). El primer parámetro de la llamada de la línea 18 es el contrato: la interfaz IHelloWorld que ya habíamos definido.

Con esos datos, el cliente puede invocar a nuestro servidor:

 

1 Imports System 2 Imports System.ServiceModel 3 Imports WCFHelloWorldLibrary 4 5 Module HelloWorldClient 6 7 Sub Main() 8 Dim cf As New ChannelFactory(Of IHelloWorld)(New BasicHttpBinding(), New EndpointAddress("http://localhost:8080/WCFHelloWorldHost/HelloWorld")) 9 Dim service As IHelloWorld = cf.CreateChannel() 10 Console.WriteLine(service.HelloWorld("Adam")) 11 Console.WriteLine("Press enter to end") 12 Console.ReadLine() 13 End Sub 14 15 End Module 16


En este cliente, se usó una clase ChannelFactory, que usa generics, y necesita que le pasemos el tipo a implementar. La factoría de canales tiene el gran método CreateChannel que devuelve un objeto que construye en el momento, que es un proxy, un objeto en el cliente, que implementa automáticamente el tipo que le pasamos como parámetro a la factoría, en este caso, un IHelloWorld. Esa es la “magia” de la factoría: analizando el tipo, implementa con generación de código (creo que usando CodeDom), todo el proxy que por debajo invocará al servidor. Dos parámetros que necesita la ChannelFactory en su construcción son el binding, y la dirección del endpoint (vemos que ésta incluye el nombre /HelloWorld). Tanto la dirección como el binding deben coincidir con el que está definido en el servidor. Pero recordemos: el servidor puede haber expuesto una implementación, con varias direcciones de endpoint y otros bindings.


Lanzamos ambos proyectos (el cliente y el servidor), ya sea configurando la solución para que lance ambos, o lanzando cada uno para depurar, o luego de armar la solución, los podemos lanzar cada uno desde una línea de comando.


Lo importante es comprender:


- El cliente sólo necesita la interfaz, el contrato, y dónde ubicar al servidor


- El servidor levanta un objeto que expone nuestra implementación, usando una dirección, binding, y contrato


Veremos más adelante que podemos implementar cómo levanta el servicio, y cómo se lo referencia en el cliente, mediante sendos archivos de configuración en ambos proyectos.


Nos leemos!


Angel “Java” Lopez
http://www.ajlopez.com/

This entry was posted in 1389, 3282. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>