miércoles, 8 de agosto de 2007

Montar un servicio WCF en 10 pasos

Para los que no conozcáis Windows Comunication Foundation (WCF para los amigos) os dejo unos cuantos enlaces muy recomendables:

Visión Global de Arquitectura de Windows Communication Foundation

Artículos de Aaron Skonard en MSDN Magazine (aunque los veáis en inglés, redirecciona a los artículos en castellano)

Artículos de Juval Lowy en MSDN Magazine (lo mismo que los de Skonnard)

Fundamentals of WCF Security – Michele Leroux Bustamante (en inglés, pero merece el esfuerzo)

Blog de Oskar Álvarez en Geeks.ms

En este post me voy a centrar en la implementación de un servicio WCF muy básico y con pasos muy concretos (algunos mucho más fáciles que otros).

Empecemos, en Visual Studio creamos una solución en blanco (a mi me gusta trabajar así, cada cual con sus manías), a la que añadimos dos proyectos de consola (con C#): Host y Cliente.

Y ahora vamos por partes:

Proyecto Host

1. Agregar referencia al ensamblado System.ServiceModel.

2. Definir una interface con el atributo [ServiceContract] para indicar que es la que define el contrato de WCF. Los métodos de esta interface que se vayan a exponer en deben incluir el atributo [OperationContract].




[ServiceContract]
public interface IClase
{
[OperationContract]
string Funcion1();

[OperationContract]
int Funcion2();

// Este método no se expone porque no tiene el atributo
//[OperationContract]
void MetodonoImplementado();
}


3. Definir una clase que implemente la interface IClase (en un futuro post explicaré cómo se implementa una interface con sólo dos clics).



class Clase : IClase
{
string IClase.Funcion1() { return "Respuesta"; }

int IClase.Funcion2(){ return 10; }

void IClase.MetodonoImplementado(){ return; }
}




4. Añadimos un fichero de configuración (app.config) al proyecto, para establecer las propiedades del servicio.


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!--Comportamiento se define un poco más abajo, en la sección BEHAVIORS-->
<service name="Host.Clase" behaviorConfiguration="Comportamiento">
<host>
<!--Se establece la URL del servicio-->
<baseAddresses>
<add baseAddress="http://localhost:8000/WCF/"/>
</baseAddresses>
</host>
<!--En el enpoint se define el ABC de los servicios WCF, Address, Binding y Contract-->
<endpoint address="Clase"
binding="wsDualHttpBinding"
contract="Host.IClase"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Comportamiento">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>




5. En el método Main() iniciamos el servicio.



class Program
{
static void Main(string[] args)
{
Type tipo = typeof(Clase);
using (ServiceHost miHost = new ServiceHost(tipo))
{
miHost.Open();
Console.WriteLine("Servicio en ejecución");
Console.WriteLine("Pulse una tecla para salir...");
Console.ReadKey();

miHost.Close();
}
}




6. Ejecutamos únicamente el proyecto Host.

7. Desde la consola de Visual Studio * ejecutamos la herramienta svcutil.exe, que creará los ficheros que servirán de proxy entre el cliente y el servicio.




Se crean 2 ficheros:
- Clase.cs - definición del proxy.
- Output.config - fichero de configuración, que debe ser renombrado como
app.config para los proyectos Windows (web.config para proyectos Web)

* Consola de Visual Studio, la podemos encontrar en: Inicio - Todos los programas - Microsoft Visual Studio 2005 - Herramientas de Visual Studio


Paramos la ejecución y pasamos al otro proyecto.

Proyecto Cliente

8. Agregamos la referencia al ensamblado System.ServiceModel, igual que el paso 1 del proyecto Host.

9. Añadimos los ficheros que genera la herramienta svcutil.exe (paso 7 del proyecto Host), Clase.cs y app.config.

10. En el método Main() iniciamos el proxy y ejecutamos los métodos.

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Pulse cualquier tecla cuando el servicio esté iniciado...");
Console.ReadKey();

using (ClaseClient proxy = new ClaseClient(“WSDualHttpBinding_IClase”))
{
Console.WriteLine(proxy.Funcion1());
Console.WriteLine(proxy.Funcion2().ToString());
Console.WriteLine("Pulse cualquier tecla para salir...");
Console.ReadKey();
proxy.Close();
}
}
}




Ya lo tenemos todo listo, vamos a probarlo, para ello tenemos que ejecutar los dos proyectos al mismo tiempo, por lo que en las propiedades de la solución hay que establecer Proyectos de inicio múltiples y establecer la acción de ambos proyectos a Iniciar, y ejecutar (F5).



Por supuesto que WCF es mucho más complejo, pero como toma de contacto creo que está bien, en próximos post entraremos en profundidad en más características.

4 comentarios:

jmlero dijo...

Hola:

Creo que hay un error en el paso 10, en la linea donde declaras el proxy
using (ClaseClient proxy = new ClaseClient(“WSHttpBinding_Iclase”))
cuando deberia aparecer using (ClaseClient proxy = new ClaseClient("BasicHttpBinding_IClase"))

Gracias por el post, está bien explicado y me ha sido de mucha ayuda. Espero que sigas hablando sobre WCF.

pbousan dijo...

Tienes razón jmlero, ya está corregido, pero le he puesto "WSDualHttpBinding_IClase" que también funciona.

El WCF lo tengo un poco abandonado últimamente, pero en cuanto tenga algo interesante que poner no dudes que haré un post ;)

Admirador dijo...

Cómo se puede hacer balanceo de servicios WCF (net.tcp) ?.

Por ejemplo, tengo varios servicios net.tcp en una maquina, pero no ´se si aguantarán 200 usuarios conectandose desde aplicaciones windows a esos servicios.

Gracias y saludos.

Pablo Bouzada dijo...

@Admirador

te aconsejo que le eches un vistazo a este link.

Aunque si lo que te interesa es amortiguar la entrada de paquetes en los servicios, igual te interesa más usar un sistema de encolamiento como MSMQ