Partager via


Duplex

L’exemple Duplex montre comment définir et implémenter un contrat duplex. La communication duplex se produit lorsqu’un client établit une session avec un service et donne au service un canal sur lequel le service peut renvoyer des messages au client. Cet exemple est basé sur la section Getting Started. Un contrat duplex est défini comme une paire d’interfaces : une interface principale du client vers le service et une interface de rappel du service au client. Dans cet exemple, l’interface ICalculatorDuplex permet au client d’effectuer des opérations mathématiques, en calculant le résultat sur une session. Le service retourne les résultats sur l’interface ICalculatorDuplexCallback . Un contrat duplex nécessite une session, car un contexte doit être établi pour mettre en corrélation l’ensemble des messages envoyés entre le client et le service.

Remarque

La procédure d’installation et les instructions de génération de cet exemple se trouvent à la fin de cette rubrique.

Dans cet exemple, le client est une application console (.exe) et le service est hébergé par les services IIS (Internet Information Services). Le contrat duplex est défini comme suit :

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

La CalculatorService classe implémente l’interface principale ICalculatorDuplex . Le service utilise le mode d’instance PerSession pour conserver le résultat de chaque session. Une propriété privée appelée Callback est utilisée pour accéder au canal de rappel permettant de communiquer avec le client. Le service utilise le rappel pour renvoyer des messages au client via l’interface de rappel.

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

Le client doit fournir une classe qui implémente l’interface de rappel du contrat duplex, pour recevoir des messages du service. Dans l’exemple, une CallbackHandler classe est définie pour implémenter l’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);
   }
}

Le proxy généré pour le contrat duplex requiert un InstanceContext qui doit être fourni lors de la construction. La classe InstanceContext est utilisée comme site pour l'objet qui implémente l'interface de rappel et gère les messages envoyés par le service. Un InstanceContext est construit avec une instance de la CallbackHandler classe. Cet objet gère les messages envoyés du service au client sur l’interface de rappel.

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

La configuration a été modifiée pour fournir une liaison qui prend en charge la communication de session et la communication duplex. La wsDualHttpBinding prend en charge la communication de session et permet la communication duplex en fournissant deux connexions HTTP, une pour chaque direction. Sur le service, la seule différence au niveau de la configuration réside dans la liaison utilisée. Sur le client, vous devez configurer une adresse que le serveur peut utiliser pour se connecter au client, comme indiqué dans l’exemple de configuration suivant.

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

Lorsque vous exécutez l’exemple, vous voyez les messages retournés au client sur l’interface de rappel envoyée à partir du service. Chaque résultat intermédiaire est affiché, suivi de l’équation entière lors de l’achèvement de toutes les opérations. Appuyez sur Entrée pour arrêter le client.

Pour configurer, générer et exécuter l’exemple

  1. Assurez-vous d’avoir effectué la Procédure d’installation unique pour les exemples Windows Communication Foundation.

  2. Pour générer l’édition C#, C++ ou Visual Basic .NET de la solution, suivez les instructions de création des exemples Windows Communication Foundation.

  3. Pour exécuter l’exemple dans une configuration à un ou plusieurs ordinateurs, conformez-vous aux instructions figurant dans la rubrique Exécution des exemples Windows Communication Foundation.

    Importante

    Lors de l’exécution du client dans une configuration inter-ordinateurs, veillez à remplacer « localhost » à la fois dans l’attribut address<du point de terminaison> de <l’élément client> et l’attribut clientBaseAddress de l’élément <de liaison> de l’élément <wsDualHttpBinding> par le nom de l’ordinateur approprié, comme indiqué dans les éléments suivants :

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