Compartilhando portas através do protocolo TCP


Ao criar um serviço WCF, podemos disponibilizá-lo através do protocolo TCP (net.tcp), utilizando uma porta específica. Uma vez que voce publica esse serviço, nenhum outro serviço naquela mesma máquina poderá utilizar aquela porta ao mesmo tempo, e se fizer isso, uma exceção do tipo AddressAlreadyInUseException será disparada exibindo a seguinte mensagem: There is already a listener on IP endpoint [MachineName]:[Port].  Make sure that you are not trying to use this endpoint multiple times in your application and that there are no other applications listening on this endpoint.

Podemos não perceber mas o Windows permite o compartilhamento de uma mesma porta TCP para expor múltiplas aplicações. Um exemplo disso é o HTTP, que permite múltiplas aplicações estarem acessíveis através da porta 80 do protocolo TCP. Isso é possível graças à um listener (HTTP.SYS) que o IIS possue e que, baseando-se no conteúdo da mensagem, encaminha a requisição para a aplicação correspondente processá-la.

Ao instalar o .NET Framework, um serviço chamado Net.Tcp Port Sharing Service é instalado no Windows, dando a possibilidade de múltiplos serviços WCF compartilharem a mesma porta TCP, assim como o HTTP. Esse serviço (hospedado através do processo SMSvcHost.exe (C:WindowsMicrosoft.NETFrameworkv3.0Windows Communication Foundation)) tem a finalidade de inspecionar a mensagem, extrair o endereço de destino, e baseando-se nele, encaminhar a requisição para a aplicação que a processará.

Além deste serviço funcionando, ainda é necessário uma pequena configuração no código que expõe serviço WCF. O binding NetTcpBinding possui uma propriedade booleana chamada PortSharingEnabled que, por padrão, é definida como False. Voce deverá definí-la como True para todos os serviços que desejarem compartilhar uma porta TCP específica. Ao fazer isso, o WCF se encarrega de iniciar automaticamente o serviço Net.Tcp Port Sharing Service, mas voce pode fazer isso manualmente, ou ainda alterar a configuração do serviço para ele ser inciado automaticamente quando o sistema operacional entrar no ar. O trecho de código abaixo ilustra como podemos proceder para configurar o endpoint com o binding e habilitando o compartilhamento da porta TCP:

host.AddServiceEndpoint(
    typeof(IContrato),
    new NetTcpBinding() { PortSharingEnabled = true }, 
    new Uri(“net.tcp://localhost:7373/NomeDoServico/Cadastro”));

Como os serviços irão compartilhar a mesma porta, a distinção da aplicação é determinada pela URI como um todo, ou seja, o que vem depois da porta na URI do serviço precisa ser diferente entre os serviços, caso contrário voce terá o mesmo problema que antes.

Com esta técnica, vamos permitir múltiplas aplicações coexistirem fisicamente na mesma máquina, mas em processos separados, compartilhando a mesma infraestrutura de rede, melhorando a segurança, já que podemos diminiur a superfície de ataque não exigindo a abertura de portas no firewall de forma aleatória.

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s