Dectetando a desconexão


Um cenário muito comum em serviços, é a capacidade que os mesmos tem de conseguir invocar algum método do lado do cliente, em resposta ou notificação à algum acontecimento que ocorreu. Isso é conhecido no WCF como comunicação duplex, onde você cria um contrato e que o cliente será obrigado a implementá-lo para que, eventualmente, seja notificado de que algo aconteceu. Para maiores detalhes em como implementar isso, consulte esse artigo ou este vídeo.

Para extrair o canal de comunicação entre o serviço e o cliente, utilizamos o método genérico GetCallbackChannel<T> da classe OperationContext. Esse método retorna uma espécie de proxy, que também implementa a interface de callback, especificada através do parâmetro genérico T. Como a ideia é armazená-lo para mais tarde invocar, pode acontecer deste cliente já não estar mais online, e o canal de comunicação já encontra-se em um estado “inválido”.

Se você não se atentar à esse detalhe e, incondicionalmente, invocar o callback, você receberá uma exceção do tipo CommunicationObjectAbortedException, informando que o canal de comunicação com o respectivo cliente foi abortado. Antes de mostrar como dectectar a desconexão, precisamos conhecer um novo tipo fornecido pelo próprio WCF, e que tem um papel extremamente importante dentro deste framework: a interface ICommunicationObject.

Essa interface define um contrato para todos os objetos de comunicação dentro do WCF, gerenciando as conexões que são relizadas através dos métodos Open, Close e Abort (e suas versões assíncronas). Essa interface ainda fornece uma propriedade chamada State, que retorna uma das opções definidas no enumerador CommunicationState. Além disso, ela ainda fornece eventos que são disparados tão logo quando o canal entrar em um estado diferente. Entre os eventos, temos: OpenedClosed e Faulted.

Apesar do método GetCallbackChannel<T> retornar a instância tipo genérico especificado em T, ele pode ser convertido em ICommunicationObject, onde você terá acesso à todos os membros que vimos acima, correspondentes ao cliente que você deseja se comunicar. Tendo acesso a está interface, você tem duas opções para identificar a desconexão. A primeira delas é antes de invocar o callback, avaliar a propriedade State, e se ela ainda estiver aberta, você pode invocar sem maiores problemas. O exemplo abaixo ilustra isso:

ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();

if (((ICommunicationObject)callback).State == CommunicationState.Opened)
    callback.OnCallback(“Algum Parametro”);

A segunda opção consiste em assinar o evento Closed, ou dependendo da situação, o Faulted, que serão disparados quando o canal de comunicação for fechado ou quando ele entrar em um estado falho, respectivamente. Dessa forma você pode ser notificado quando isso acontecer, e tormar alguma decisão em cima disso. O código abaixo ilustra como proceder para assinar o evento Closed:

((ICommunicationObject)callback).Closed += (sender, args) => Console.WriteLine(“Fechou!”);

Esse tipo de técnica é comumente utilizada quando armazenamos do lado do serviço, a referência para um ou vários clientes, como é o caso de aplicações de chat ou algum modelo de publish-subscribe.

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