Compartilhar via


Duplex

O exemplo Duplex demonstra como definir e implementar um contrato duplex. A comunicação duplex ocorre quando um cliente estabelece uma sessão com um serviço e fornece ao serviço um canal no qual o serviço pode enviar mensagens de volta ao cliente. Este exemplo é baseado na Introdução. Um contrato duplex é definido como um par de interfaces, uma interface primária do cliente para o serviço e uma interface de retorno de chamada do serviço para o cliente. Neste exemplo, a interface ICalculatorDuplex permite que o cliente execute operações matemáticas, calculando o resultado em uma sessão. O serviço retorna resultados na interface ICalculatorDuplexCallback. Um contrato duplex requer uma sessão, pois um contexto precisa ser estabelecido para correlacionar o conjunto de mensagens enviadas entre o cliente e o serviço.

Observação

O procedimento de instalação e as instruções de compilação dessa amostra estão no final deste tópico.

Nesta amostra, o cliente é um aplicativo de console (.exe) e o serviço é hospedado pelos Serviços de Informações da Internet (IIS). O contrato duplex é definido da seguinte maneira:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
                 CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
    [OperationContract(IsOneWay = true)]
    void Clear();
    [OperationContract(IsOneWay = true)]
    void AddTo(double n);
    [OperationContract(IsOneWay = true)]
    void SubtractFrom(double n);
    [OperationContract(IsOneWay = true)]
    void MultiplyBy(double n);
    [OperationContract(IsOneWay = true)]
    void DivideBy(double n);
}

public interface ICalculatorDuplexCallback
{
    [OperationContract(IsOneWay = true)]
    void Result(double result);
    [OperationContract(IsOneWay = true)]
    void Equation(string eqn);
}

A classe CalculatorService implementa a interface ICalculatorDuplex primária. O serviço usa o modo de instância PerSession para manter o resultado de cada sessão. Uma propriedade privada chamada Callback é usada para acessar o canal de retorno de chamada para o cliente. O serviço usa o retorno de chamada para enviar mensagens de volta ao cliente por meio da interface de retorno de chamada.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
    double result = 0.0D;
    string equation;

    public CalculatorService()
    {
        equation = result.ToString();
    }

    public void Clear()
    {
        Callback.Equation($"{equation} = {result}");
        equation = result.ToString();
    }

    public void AddTo(double n)
    {
        result += n;
        equation += $" + {n}";
        Callback.Result(result);
    }

    //...

    ICalculatorDuplexCallback Callback
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
        }
    }
}

O cliente deve fornecer uma classe que implemente a interface de retorno de chamada do contrato duplex para receber mensagens do serviço. No exemplo, uma classe CallbackHandler é definida para implementar a interface ICalculatorDuplexCallback.

public class CallbackHandler : ICalculatorDuplexCallback
{
   public void Result(double result)
   {
      Console.WriteLine("Result({0})", result);
   }

   public void Equation(string equation)
   {
      Console.WriteLine("Equation({0}", equation);
   }
}

O proxy gerado para um contrato duplex requer que uma InstanceContext seja fornecida após a construção. Essa InstanceContext é usada como o site para um objeto que implementa a interface de retorno de chamada e manipula mensagens que são enviadas de volta do serviço. Uma InstanceContext é construída com uma instância da classe CallbackHandler. Esse objeto manipula mensagens enviadas do serviço para o cliente na interface de retorno de chamada.

// Construct InstanceContext to handle messages on callback interface.
InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

// Create a client.
CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);

Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
Console.WriteLine();

// Call the AddTo service operation.
double value = 100.00D;
client.AddTo(value);

// Call the SubtractFrom service operation.
value = 50.00D;
client.SubtractFrom(value);

// Call the MultiplyBy service operation.
value = 17.65D;
client.MultiplyBy(value);

// Call the DivideBy service operation.
value = 2.00D;
client.DivideBy(value);

// Complete equation.
client.Clear();

Console.ReadLine();

//Closing the client gracefully closes the connection and cleans up resources.
client.Close();

A configuração foi modificada para fornecer uma associação que dê suporte à comunicação de sessão e à comunicação duplex. O wsDualHttpBinding dá suporte à comunicação de sessão e permite comunicação duplex fornecendo conexões HTTP duplas, uma para cada direção. No serviço, a única diferença na configuração é a associação usada. No cliente, você deve configurar um endereço que o servidor pode usar para se conectar ao cliente, conforme mostrado na configuração de exemplo a seguir.

<client>
  <endpoint name=""
            address="http://localhost/servicemodelsamples/service.svc"
            binding="wsDualHttpBinding"
            bindingConfiguration="DuplexBinding"
            contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
</client>

<bindings>
  <!-- Configure a binding that support duplex communication. -->
  <wsDualHttpBinding>
    <binding name="DuplexBinding"
             clientBaseAddress="http://localhost:8000/myClient/">
    </binding>
  </wsDualHttpBinding>
</bindings>

Ao executar o exemplo, você verá as mensagens que são retornadas ao cliente na interface de retorno de chamada que é enviada do serviço. Cada resultado intermediário é exibido, seguido por toda a equação após a conclusão de todas as operações. Pressione ENTER para desligar o cliente.

Para configurar, compilar, e executar o exemplo

  1. Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. Para compilar a edição C#, C++ ou Visual Basic .NET da solução, siga as instruções em Como compilar os exemplos do Windows Communication Foundation.

  3. Para executar a amostra em uma configuração de computador único ou cruzado, siga as instruções em Como executar os exemplos do Windows Communication Foundation.

    Importante

    Ao executar o cliente em uma configuração entre máquinas, substitua o “localhost” no atributo address do <ponto de extremidade> do elemento do <cliente> e no atributo clientBaseAddress do elemento de <associação> do elemento <wsDualHttpBinding> pelo nome do computador apropriado, conforme mostrado no exemplo a seguir:

    <client>
        <endpoint name = ""
        address="http://service_machine_name/servicemodelsamples/service.svc"
        ... />
    </client>
    ...
    <wsDualHttpBinding>
        <binding name="DuplexBinding" clientBaseAddress="http://client_machine_name:8000/myClient/">
        </binding>
    </wsDualHttpBinding>