Dupleks

W przykładzie dupleksowym pokazano, jak definiować i implementować kontrakt dwukierunkowy. Komunikacja dwukierunkowa występuje, gdy klient ustanawia sesję z usługą i zapewnia usłudze kanał, na którym usługa może wysyłać komunikaty z powrotem do klienta. Ten przykład jest oparty na rozpoczynaniu pracy. Kontrakt dwukierunkowy jest definiowany jako para interfejsów — podstawowy interfejs od klienta do usługi i interfejs wywołania zwrotnego z usługi do klienta. W tym przykładzie ICalculatorDuplex interfejs umożliwia klientowi wykonywanie operacji matematycznych, obliczanie wyniku w ramach sesji. Usługa zwraca wyniki w interfejsie ICalculatorDuplexCallback . Kontrakt dwukierunkowy wymaga sesji, ponieważ należy ustanowić kontekst, aby skorelować zestaw komunikatów wysyłanych między klientem a usługą.

Uwaga

Procedura instalacji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.

W tym przykładzie klient jest aplikacją konsolową (.exe), a usługa jest hostowana przez usługi Internet Information Services (IIS). Kontrakt dwukierunkowy jest definiowany w następujący sposób:

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

Klasa CalculatorService implementuje interfejs podstawowy ICalculatorDuplex . Usługa używa PerSession trybu wystąpienia, aby zachować wynik dla każdej sesji. Właściwość prywatna o nazwie Callback służy do uzyskiwania dostępu do kanału wywołania zwrotnego do klienta. Usługa używa wywołania zwrotnego do wysyłania komunikatów z powrotem do klienta za pośrednictwem interfejsu wywołania zwrotnego.

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

Klient musi podać klasę, która implementuje interfejs wywołania zwrotnego kontraktu dwustronnego na potrzeby odbierania komunikatów z usługi. W przykładzie zdefiniowano klasę CallbackHandler w celu zaimplementowania interfejsu 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);
   }
}

Serwer proxy generowany na potrzeby kontraktu dwustronnego wymaga InstanceContext podania elementu na budowę. Jest to InstanceContext używane jako lokacja obiektu, który implementuje interfejs wywołania zwrotnego i obsługuje komunikaty wysyłane z powrotem z usługi. Obiekt InstanceContext jest skonstruowany z wystąpieniem CallbackHandler klasy . Ten obiekt obsługuje komunikaty wysyłane z usługi do klienta w interfejsie wywołania zwrotnego.

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

Konfiguracja została zmodyfikowana w celu zapewnienia powiązania obsługującego komunikację sesji i komunikację dwukierunkową. Obsługuje wsDualHttpBinding komunikację sesji i umożliwia komunikację dwukierunkową, zapewniając podwójne połączenia HTTP, po jednym dla każdego kierunku. W usłudze jedyną różnicą w konfiguracji jest powiązanie, które jest używane. Na kliencie należy skonfigurować adres, za pomocą którego serwer może nawiązać połączenie z klientem, jak pokazano w poniższej przykładowej konfiguracji.

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

Po uruchomieniu przykładu zobaczysz komunikaty, które są zwracane do klienta w interfejsie wywołania zwrotnego wysyłanego z usługi. Każdy wynik pośredni jest wyświetlany, po którym następuje całe równanie po zakończeniu wszystkich operacji. Naciśnij klawisz ENTER, aby zamknąć klienta.

Aby skonfigurować, skompilować i uruchomić przykład

  1. Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.

  2. Aby skompilować wersję rozwiązania W#, C++lub Visual Basic .NET, postępuj zgodnie z instrukcjami w temacie Kompilowanie przykładów programu Windows Communication Foundation.

  3. Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.

    Ważne

    Podczas uruchamiania klienta w konfiguracji między maszynami należy zastąpić ciąg "localhost" zarówno address<atrybutem punktu końcowego><elementu klienta>, jak i clientBaseAddress atrybutem <elementu< powiązania> elementu wsDualHttpBinding> nazwą odpowiedniej maszyny, jak pokazano poniżej:

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