9 de diciembre de 2015

netTcpBinding con Windows Service Host

Lo primero a hacer es crear un proyecto de tipo WCF Service Library con nombre WCF4Windows


antes de continuar hacer la observación que elimine las clase Service1.cs y la interface IService1.cs que el proyecto de WCF Service Library creo por defecto y en cambio se agregó una nueva clase WCFService.cs y una nueva interface IWCFService.cs de tal manera que el Solution Explorer del proyecto queda de la siguiente manera
el objetivo de la entrada es hospedar y consumir un servicio WCF hospedado en Windows Service, bajo esa premisa el sencillísimo código para la interfaz IWCFService es
using System.ServiceModel;

namespace WCF4Windows
{
    [ServiceContract]
    interface IWCFService
    {
        [OperationContract]
        string saludo(string nombre);
    }
}
y la clase WCFService que implementa la interfaz anterior es
namespace WCF4Windows
{
    public class WCFService:IWCFService
    {
        public string saludo(string nombre)
        {
            return string.Format("Hola {0} has creado un enlace a un servicio hospedado en Windows", nombre);
        }
    }
}
aquí lo interesante viene en la configuración del App.config pues se creara un endpoint utilizando netTcpBinding en lugar del BasicHttpBinding que viene por defecto al crear cualquier proyecto WCF, también se debe definir un endpoint utilizando el mexTcpBinding pues es la manera en que se publica el metadata del servicio

   


  















  











Ahora bien, hay algunos puntos a tener en cuenta:
- Atributo del serviceMetadata 'httpGetEnabled' debe establecerse en "falso". Esto permitirá descubrir metadatos de servicio WCF sobre protocolo que no sea HTTP.

- Tenga en cuenta que estamos usando 'mexTcpBinding' para el endpoint mex. También puede utilizar 'mexHttpBinding', pero luego tienes que configurar el atributo 'httpGetEnabled' a 'True' y deberas localizar el Servicio WCF haciendo uso de la dirección http en lugar de net.tcp.

- Es importante que especifique el baseAddress para su punto final. Esto ayudará al Windows Service para que encuentre su servicio WCF.

con lo anterior se ha creado un sencillo...sencillísimo ejemplo de WCF Service Library Project utilizando netTcpBinding, ahora viene la parte de hospedarlo en un Windows Service, para ello agregamos un nuevo proyecto a la solución y esta vez sera del tipo Windows Service con nombre WService



y debemos agregar dos referencias al proyecto de Windows Service, una para el proyecto de WCF Service Library y otro para System.ServiceModel



a continuación vamos a copiar el App.config que se creo en el WCF Service Library y lo pegaremos en el Windows Service Project a fin de tener la misma configuración para ambos proyectos, el Service Explorer para nuestra aplicacion deberia de momento estar como muestro en la imagen, estan sombreadas las referencias agregadas y el App.config recién agregado:

Ahora se debe dar click derecho sobre la clase Service1.cs del proyecto de Windows Service y seleccionar View Designer


Luego en la venta de View Designer que acaba de abrirse damos click derecho y seleccionamos Add Installer tal como se muestra en la figura

La accion anterior agrego un nuevo elemento al proyecto de Windows Service, muestro el Solution Explorer resultane con el nuevo elemento resaltado

el ProjectInstaller utiliza para su configuracion un serviceProcessInstaller1 y serviceInstaller1, la vista diseño queda de la siguiente manera

damos click derecho sobre serviceProcessInstaller1 y seleccionamos propiedades, en propiedades cambiamos el accountattribute a NetworkServices



ahora damos click derecho sobre serviceInstaller1 que es el otro elemento de ProjectInstaller.cs y seleccionamos propiedades, en las propiedades seleccionamos el atributo Start Type y lo colocamos en Automatic

Ahora toca modificar el código del Windows Service a fin de que hospede el servicio WCF, el código de Service1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using WCF4Windows;

namespace WService
{
    public partial class Service1 : ServiceBase
    {
        internal static ServiceHost myHost = null;
        BackgroundWorker worker;
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        }
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (myHost != null)
            {
                myHost.Close();
            }

            myHost = new ServiceHost(typeof(WCF4Windows.WCFService));
            myHost.Open();
        }

        protected override void OnStop()
        {
            if (myHost != null)
            {
                myHost.Close();
                myHost = null;
            }

        }
    }
}
listo, ahora tenemos que seleccionar Build Application y verificar que no se de ningún error, si todo va bien se tendrá un archivo ejecutable en el folder bin/debug dentro de la solución del Windows Service, para encontrarlo solo basta con dar click derecho sobre la solución y seleccionar Windows Explorer, el ejecutable se muestra en la imagen, ademas aprovecho en la imagen para mostrar como copiar la direcion en donde se encuentra el ejecutable pues sera util a continuación


ahora se debe abrir la consola de comando de Visual Studio y utilizar el installutil.exe junto con la ruta del WService que recién copiamos y la aplicación WService.exe


Procedemos a verificar que se ha agregado el servicio exitosamente, para ello desde la ventana de comandos de Windows escribimos services.msc y damos enter, con lo anterior se abrirá la ventana de servicios de Windows desde la cual podemos encontrar el servicio que recién agregamos


y para agregar una referencia desde otro proyecto al Windows Service recién creado agregar la dirección especificada en el App.config y agregar al final /mex tal como se muestra en la figura






Como punto final les advierto que la herramienta que utilizo para mostrar el código del Web.config siempre altera el codigo, me imagino debe ser por reglas de seguridad de Blogger, por tal razón dejo una imagen del contenido del archivo Web.config para que sirva de guia