Sessão e Operações One-way


O WCF fornece várias tipos de mensagens, e entre eles, temos as operações one-way. Esse tipo de operação deve ser utilizado quando o cliente não precisa de qualquer retorno (resultado ou erro), uma espécie de fire-and-forget.

Esse tipo de mensagem pode ter um comportamento estranho quando exposto através de um binding que suporte sessões nativamente, como é o caso do NetTcpBinding. O protocolo TCP estabelece um canal duplex entre o cliente e o serviço, mantendo uma espécie de conexão ativa, onde a qualquer momento um pode tranquilamente se comunicar com o outro.

É importante dizer que mensagens one-way não são assíncronas, mas o tempo de entrega é tolerável. O maior problema, do qual falava anteriormente, refere-se ao fechamento do proxy depois da mensagem one-way disparada ao destinatário, ou seja, quando invocamos a operação one-way, tão logo já conseguimos continuar trabalhando na aplicação cliente, mas se tentarmos fechar o proxy, ficaremos bloqueados até que a operação one-way seja completamente finalizada. Mas se a ideia é disparar e esquecer, porque eu preciso esperar, mantendo o proxy aberto até finalizar a operação?

Para ter o comportamento fire-and-forget a sério, uma das alternativas que temos é habilitar as mensagens (ou sessões) confiáveis. Isso tornará a comunicação entre as partes muito mais descritiva, onde além das mensagens normais, ainda haverão uma porção de outras mensagens que são geradas pelo protocolo WS-ReliableMessaging, indicando se a mensagem foi entregue, quando ela foi entregue e a ordem de chegada, permitindo ao cliente continuar sem a necessidade de esperar. Para habilitar as mensagens confiáveis, consulte este artigo.

Apesar disso funcionar, a comunicação entre as partes ficará bem mais volumosa, já que várias mensagens de infraestrutura serão trocadas para garantir a entrega da mensagem principal. Para evitar todo este overhead causado pelo protocolo WS-ReliableMessaging, podemos recorrer a construção de um binding customizado, empilhando os vários elementos para compor a comunicação via TCP, mas com um detalhe, que é a adição de um novo elemento, chamado de OneWayBindingElement. A adição deste elemento fará com que o canal de comunicação se comporte semanticamente como um fire-and-forget. O código abaixo ilustra o seu uso, via código imperativo e declarativo, respectivamente:

private static Binding CreateOneWayTcpBinding()
{
    BindingElementCollection currentElements = new NetTcpBinding().CreateBindingElements();
    BindingElementCollection bindingElements = new BindingElementCollection();

    bindingElements.Add(new OneWayBindingElement());

    foreach (BindingElement be in currentElements)
        bindingElements.Add(be);

    return new CustomBinding(bindingElements);
}

<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name=”OneWayTcpBinding”>
        <oneWay />
        <binaryMessageEncoding />
        <tcpTransport />
      </binding>
    </customBinding>
  </bindings>
</system.serviceModel>

Só que utilizar este procedimento possui dois detalhes importantes: o primeiro é que ao configurá-lo, o canal somente permitirá a comunicação através do modelo one-way, e com isso, o contrato que você está expondo obrigatoriamente precisa definir todas as operações neste mesmo modelo. Se tiver qualquer operação neste contrato do tipo request/reply, ao tentar subir o serviço, você irá se deparar com uma exceção do tipo InvalidOperationException, indicando justamente isso. Se você conseguir garantir com que todas as operações sejam one-way, então utilizar esta técnica pode trazer uma grande melhora em performance, quando comparado à opção anterior.

O segundo detalhe é com relação ao modelo de gerenciamento de instância. Mesmo que você diga ao serviço que ele deve ser PerSession, ele não conseguirá manter a sessão, ou seja, terá o comportamento do modelo PerCall, pois cada chamada para uma operação one-way encerrará a “sessão”.

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