Hospedando um serviço WCF em um Windows NT Service

Continuando a série de posts sobre a criação de um serviço WCF, agora vou mostrar como hospedá-lo em um serviço Windows NT Service, que deve ser feito seguindo alguns passos:

Abra a solução anterior 
Clique com o botão direito na solução e escolha a opção “Add/New Project…”

Novo Projeto 

Escolha a opção “Windows Service” e forneça um nome para o seu projeto, eu utilizei “CalculatorNTService”.

Criando um Windows Service

Adicione referência para o projeto do serviço WCF clicando com o botão direito em “References” e depois em “Add Reference…”.

image

Escolha o ServicoWCF e clique em OK.

image

Faça o mesmo para o assembly System.ServiceModel

image

Renomeie o arquivo Service1.cs para NTService.cs, o seu projeto deve ficar assim:

image

No início do arquivo adicione o código abaixo:

using System.ServiceModel;

Dentro da classe do serviço NT, crie uma propriedade do tipo ServiceHost

private ServiceHost ServiceHost { get; set; }

Preencha o conteúdo do método OnStart e do OnStop

        protected override void OnStart(string[] args)
        {
            if (ServiceHost != null)
            {
                ServiceHost.Close();
            }

            ServiceHost = new ServiceHost(typeof(ServicoWCF.CalcService));
            ServiceHost.Open();
        }

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

No final seu código deve ficar mais ou menos assim:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;

namespace CalculatorNTService
{
    public partial class NTService : ServiceBase
    {
        public NTService()
        {
            InitializeComponent();
        }

        private ServiceHost ServiceHost { get; set; }

        protected override void OnStart(string[] args)
        {
            if (ServiceHost != null)
            {
                ServiceHost.Close();
            }

            ServiceHost = new ServiceHost(typeof(ServicoWCF.CalcService));
            ServiceHost.Open();
        }

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

O próximo passo é adicionar um arquivo para armazenar as configurações do serviço WCF, para isso clique com o botão direito e escolha “Add/New Item”

image

Em seguida adicione um “Application Configuration File”

image

No arquivo “App.config” insira o código

 <?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
  <system.web> 
    <compilation debug="true" /> 
  </system.web> 
  <system.serviceModel> 
    <services> 
      <service behaviorConfiguration="ServicoWCF.Service1Behavior" 
        name="ServicoWCF.CalcService"> 
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
        <endpoint binding="netTcpBinding" bindingConfiguration="" contract="ServicoWCF.ICalcService"  /> 
        <host> 
          <baseAddresses> 
            <add baseAddress="https://localhost:8731/CalculatorService/" /> 
            <add baseAddress="net.tcp://localhost:9090/CalculatorService/" /> 
          </baseAddresses> 
        </host> 
      </service> 
    </services> 
    <behaviors> 
      <serviceBehaviors> 
        <behavior name="ServicoWCF.Service1Behavior"> 
          <serviceMetadata httpGetEnabled="True"/> 
          <serviceDebug includeExceptionDetailInFaults="False" /> 
        </behavior> 
      </serviceBehaviors> 
    </behaviors> 
  </system.serviceModel> 
</configuration>

Notem que neste exemplo estamos trabalhando com um binding do tipo Tcp, o netTcpBinding, esperando conexões na porta 9090.

Agora o próximo passo é adicionar uma maneira para instalar o serviço, repita o procedimento “Add/New Item…” e escolha a opção “Installer Class”.

image

No início do arquivo adicione o código abaixo:

using System.ServiceProcess;

Em seguida, adicione uma propriedade do tipo “ServiceProcessInstaller”

private ServiceProcessInstaller Process { get; set; }

Depois uma do tipo “ServiceInstaller”

private ServiceInstaller Service { get; set; }

No construtor da classe adicione

Process = new ServiceProcessInstaller();

Process.Account = ServiceAccount.LocalSystem;

Service = new ServiceInstaller();

Service.ServiceName = "CalculatorNTService";

Installers.Add(Process);

Installers.Add(Service);

No final sua classe deve ficar mais ou menos assim

using System;

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

using System.Configuration.Install;

using System.Linq;

using System.ServiceProcess;

namespace CalculatorNTService

{

    [RunInstaller(true)]

    public partial class ProjectInstaller : Installer

    {

        private ServiceProcessInstaller Process { get; set; }

        private ServiceInstaller Service { get; set; }

        public ProjectInstaller()

        {

            InitializeComponent();

            Process = new ServiceProcessInstaller();

            Process.Account = ServiceAccount.LocalSystem;

            Service = new ServiceInstaller();

            Service.ServiceName = "CalculatorNTService";

            Installers.Add(Process);

            Installers.Add(Service);

        }

    }

}

Agora é só compilar o projeto para gerar o executável do “Windows NT Service” e em seguida instalá-lo. Para isso abra o “Visual Studio Command Prompt” como administrador.

image

No “Visual Studio Command Prompt” navegue, com o comando cd, até o o diretório onde o “Windows NT Service” foi compilado, em seguida execute o comando:

InstallUtil CalculatorNTService.exe

Para verificar que o serviço foi instalado com sucesso abra o MMC de gerenciamento de serviços, o jeito mais fácil é pelo próprio Command Prompt executar:

Services.msc

Na tela que se abre, podemos perceber que o nosso serviço foi instalado com sucesso e pode ser iniciado pelo botão de start, no caso do Windows 7 que estou usando, a setinha verde na barra de ferramentas da tela abaixo.

image 

Para testar se o serviço está funcionando vamos utilizar a ferramenta “WCF Test Client”, que está disponível junto com a instalação do Visual Studio 2008, geralmente em C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\WcfTestClient.exe.

image

Depois de executar a ferramenta, escolha a opção “File/Add Service…” e insira o endereço do metadados do serviço, no nosso caso https://localhost:8731/CalculatorService, confirme com o botão OK.

image

Neste momento o “WCF Test Client” reconhece o serviço, suas interfaces e métodos e os exibe para teste. Notem também que o protocolo de comunicação utilizado é o NetTcpBinding.

image

Para testar, clique duas vezes em um método do serviço, por exemplo, o Add, preencha os valores dos parâmetros x e y do método e depois clique no botão Invoke.

image

Note que na parte de baixo da tela é exibida a informação do retorno do serviço, no caso do teste  realizado o valor 3.

Vale lembrar que o objetivo deste post era mostrar uma introdução de como hospedar serviços WCF utilizando serviços Windows NT e de modo algum teve objetivo de mostrar melhores práticas sobre o desenvolvimento dos mesmos.

Não esqueçam de deixar comentários, se eu esqueci de algum passo me avisem. Espero que tenham gostado e até a próxima pessoal!!!