Delen via


Duplex

Het duplex-voorbeeld laat zien hoe u een duplex-contract definieert en implementeert. Dubbelzijdige communicatie treedt op wanneer een client een sessie met een service tot stand brengt en de service een kanaal geeft waarop de service berichten naar de client kan verzenden. Dit voorbeeld is gebaseerd op aan de slag. Een dubbelzijdig contract wordt gedefinieerd als een paar interfaces: een primaire interface van de client naar de service en een callback-interface van de service naar de client. In dit voorbeeld kan de ICalculatorDuplex client wiskundige bewerkingen uitvoeren, waarbij het resultaat van een sessie wordt berekend. De service retourneert resultaten op de ICalculatorDuplexCallback interface. Voor een dubbelzijdig contract is een sessie vereist, omdat er een context tot stand moet worden gebracht om de set berichten te correleren die worden verzonden tussen de client en de service.

Notitie

De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.

In dit voorbeeld is de client een consoletoepassing (.exe) en wordt de service gehost door Internet Information Services (IIS). Het duplex-contract wordt als volgt gedefinieerd:

[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);
}

De CalculatorService klasse implementeert de primaire ICalculatorDuplex interface. De service gebruikt de PerSession instantiemodus om het resultaat voor elke sessie te behouden. Een persoonlijke eigenschap met de naam Callback wordt gebruikt voor toegang tot het callback-kanaal naar de client. De service gebruikt de callback voor het terugsturen van berichten naar de client via de callback-interface.

[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>();
        }
    }
}

De client moet een klasse opgeven waarmee de callback-interface van het duplex-contract wordt geïmplementeerd voor het ontvangen van berichten van de service. In het voorbeeld wordt een CallbackHandler klasse gedefinieerd om de ICalculatorDuplexCallback interface te implementeren.

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

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

Voor de proxy die wordt gegenereerd voor een dubbelzijdig contract, moet InstanceContext bij de bouw worden voorzien. Dit InstanceContext wordt gebruikt als de site voor een object dat de callback-interface implementeert en berichten verwerkt die vanuit de service worden teruggestuurd. Een InstanceContext wordt samengesteld met een exemplaar van de CallbackHandler klasse. Dit object verwerkt berichten die vanuit de service naar de client worden verzonden op de callback-interface.

// 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();

De configuratie is gewijzigd om een binding te bieden die zowel sessiecommunicatie als dubbelzijdige communicatie ondersteunt. De wsDualHttpBinding ondersteunt sessiecommunicatie en maakt dubbelzijdige communicatie mogelijk door dubbele HTTP-verbindingen te bieden, één voor elke richting. In de service is het enige verschil in configuratie de binding die wordt gebruikt. Op de client moet u een adres configureren dat de server kan gebruiken om verbinding te maken met de client, zoals wordt weergegeven in de volgende voorbeeldconfiguratie.

<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>

Wanneer u het voorbeeld uitvoert, ziet u de berichten die naar de client worden geretourneerd in de callback-interface die vanuit de service wordt verzonden. Elk tussenliggend resultaat wordt weergegeven, gevolgd door de volledige vergelijking na voltooiing van alle bewerkingen. Druk op Enter om de client af te sluiten.

Het voorbeeld instellen, compileren en uitvoeren

  1. Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.

  2. Als u de C#-, C++- of Visual Basic .NET-editie van de oplossing wilt bouwen, volgt u de instructies in het bouwen van de Windows Communication Foundation-voorbeelden.

  3. Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.

    Belangrijk

    Wanneer u de client uitvoert in een configuratie tussen computers, moet u 'localhost' vervangen in zowel het address kenmerk van het eindpunt van <het <clientelement>> als het clientBaseAddress kenmerk van het <bindingselement> van het< wsDualHttpBinding-element> door de naam van de juiste computer, zoals wordt weergegeven in het volgende:

    <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>