Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Olá pessoal,
Dando continuidade ao post Operações One-Way com WCF, resolvi escrever sobre uma tecnologia complementar que é o callback. O callback permite que o serviço WCF chame operações para serem executadas no lado do cliente, sendo bastante útil se utilizado em conjunto com operações one-way em cenários de longa duração.
Neste tipo de uso o cliente chama uma operação one-way, não precisa esperar o retorno do serviço e sua thread está liberada para outros processamentos, o serviço realiza o seu trabalho e quando necessário, por exemplo, no término do processamento, envia mensagens para o cliente através do callback. O diagrama de sequência abaixo ilustra o processo de comunicação:
Para que a comunicação ocorra com sucesso, é necessário que o binding utilizado suporte callback, os bindings NetTcpBinding e NetNamedPipeBinding suportam callback, pois funcionam em cima de protocolos que suportam comunicação bidirecional. Já o protocolo HTTP não suporta este tipo de comunicação, fazendo com que os bindings BasicHttpBinding ou WSHttpBinding não suportem callback. Uma alternativa para callback com HTTP é o uso do WSDualHttpBinding, que abre dois canais de comunicação HTTP: um para chamadas no sentido do cliente para o serviço e outro para chamadas do serviço para o cliente.
Para que o serviço WCF entenda o callback, é necessário definir um contrato de callback com suas operações e também indicar no ServiceContract qual o tipo que deve ser utilizado para callback, o código fica similar ao código abaixo:
interface IContractCallback
{
[OperationContract(IsOneWay=true)]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(IContractCallback))]
public interface IService
{
[OperationContract(IsOneWay=true)]
void ProcessarOneWay();
}
Do lado do cliente, é necessário informar ao serviço qual objeto é o responsável pelo callback. Para isso é necessário implementar a interface de callback e também passar uma instância desta classe para o contexto co WCF, conforme abaixo:
class MyCallback : CallbackServiceReference.IServiceCallback
{
public void OnCallback()
{
MessageBox.Show("OnCallback");
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
CallbackServiceReference.IServiceCallback callback = new MyCallback();
InstanceContext ctx = new InstanceContext(callback);
CallbackServiceReference.ServiceClient proxy =
new CallbackServiceReference.ServiceClient(ctx);
proxy.ProcessarOneWay();
}
Já do lado do serviço precisamos acessar a instância informada do objeto que gerencia o callback para conseguirmos chamar suas operações, isso deve ser feito utilizando o OperationContext, sempre utilizando a interface definida no contrato de callback, conforme abaixo:
public void ProcessarOneWay()
{
Trace.WriteLine(
string.Format("Início ProcessarOneWay - {0}", DateTime.Now));
Thread.Sleep(15000);
Trace.WriteLine(
string.Format("Fim ProcessarOneWay - {0}", DateTime.Now));
IContractCallback callback =
OperationContext.Current.GetCallbackChannel<IContractCallback>();
callback.OnCallback();
}
Com isso, é possível utilizar a infraestrutura do WCF para cenários de comunicação mais complexos entre cliente e serviço, atendendo à diversos cenários de uso. O código fonte utilizado pode ser baixado aqui.