Programowanie na poziomie kanału klienta

W tym temacie opisano sposób pisania aplikacji klienckiej programu Windows Communication Foundation (WCF) bez używania klasy i skojarzonego System.ServiceModel.ClientBase<TChannel> z nią modelu obiektów.

Wysyłanie wiadomości

Aby być gotowym do wysyłania wiadomości i odbierania i przetwarzania odpowiedzi, wymagane są następujące kroki:

  1. Utwórz powiązanie.

  2. Tworzenie fabryki kanałów.

  3. Utwórz kanał.

  4. Wyślij żądanie i przeczytaj odpowiedź.

  5. Zamknij wszystkie obiekty kanału.

Tworzenie powiązania

Podobnie jak w przypadku odbierania (zobacz Service Channel-Level Programming), wysyłanie komunikatów rozpoczyna się od utworzenia powiązania. Ten przykład tworzy nowy System.ServiceModel.Channels.CustomBinding element i dodaje element System.ServiceModel.Channels.HttpTransportBindingElement do kolekcji Elements.

Tworzenie rozwiązania ChannelFactory

Zamiast tworzyć element System.ServiceModel.Channels.IChannelListener, tym razem tworzymy element System.ServiceModel.ChannelFactory<TChannel> , wywołując ChannelFactory.CreateFactory powiązanie, w którym parametr typu to System.ServiceModel.Channels.IRequestChannel. Podczas gdy odbiorniki kanału są używane przez stronę oczekującą na komunikaty przychodzące, fabryki kanałów są używane przez stronę, która inicjuje komunikację w celu utworzenia kanału. Podobnie jak odbiorniki kanałów, fabryki kanałów muszą być otwierane jako pierwsze, zanim będą mogły być używane.

Tworzenie kanału

Następnie wywołujemy metodę ChannelFactory<TChannel>.CreateChannel w celu utworzenia elementu IRequestChannel. To wywołanie przyjmuje adres punktu końcowego, z którym chcemy komunikować się przy użyciu tworzonego nowego kanału. Po utworzeniu kanału wywołamy metodę Otwórz, aby umieścić ją w stanie gotowym do komunikacji. W zależności od charakteru transportu to wywołanie open może zainicjować połączenie z docelowym punktem końcowym lub w ogóle nic nie zrobić w sieci.

Wysyłanie żądania i odczytywanie odpowiedzi

Po otwarciu kanału możemy utworzyć komunikat i użyć metody Request kanału, aby wysłać żądanie i poczekać na powrót odpowiedzi. Gdy ta metoda zwróci, mamy komunikat odpowiedzi, który możemy odczytać, aby dowiedzieć się, jaka była odpowiedź punktu końcowego.

Zamykanie obiektów

Aby uniknąć wycieku zasobów, zamykamy obiekty używane w komunikacji, gdy nie są już wymagane.

Poniższy przykład kodu przedstawia podstawowego klienta korzystającego z fabryki kanałów w celu wysłania wiadomości i odczytania odpowiedzi.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
namespace ProgrammingChannels
{
class Client
{

    static void RunClient()
    {
        //Step1: Create a binding with just HTTP.
        BindingElement[] bindingElements = new BindingElement[2];
        bindingElements[0] = new TextMessageEncodingBindingElement();
        bindingElements[1] = new HttpTransportBindingElement();
        CustomBinding binding = new CustomBinding(bindingElements);

        //Step2: Use the binding to build the channel factory.
        IChannelFactory<IRequestChannel> factory =
        binding.BuildChannelFactory<IRequestChannel>(
                         new BindingParameterCollection());
        //Open the channel factory.
        factory.Open();

        //Step3: Use the channel factory to create a channel.
        IRequestChannel channel = factory.CreateChannel(
           new EndpointAddress("http://localhost:8080/channelapp"));
        channel.Open();

        //Step4: Create a message.
        Message requestmessage = Message.CreateMessage(
            binding.MessageVersion,
            "http://contoso.com/someaction",
             "This is the body data");
        //Send message.
        Message replymessage = channel.Request(requestmessage);
        Console.WriteLine("Reply message received");
        Console.WriteLine("Reply action: {0}",
                              replymessage.Headers.Action);
        string data = replymessage.GetBody<string>();
        Console.WriteLine("Reply content: {0}", data);

        //Step5: Do not forget to close the message.
        replymessage.Close();
        //Do not forget to close the channel.
        channel.Close();
        //Do not forget to close the factory.
        factory.Close();
    }
    public static void Main()
    {
        Console.WriteLine("Press [ENTER] when service is ready");
        Console.ReadLine();
        RunClient();
        Console.WriteLine("Press [ENTER] to exit");
        Console.ReadLine();
    }
}
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Configuration

Namespace ProgrammingChannels
    Friend Class Client

        Private Shared Sub RunClient()
            'Step1: Create a binding with just HTTP.
            Dim bindingElements(1) As BindingElement = {New TextMessageEncodingBindingElement(), _
                                                        New HttpTransportBindingElement()}
            Dim binding As New CustomBinding(bindingElements)

            'Step2: Use the binding to build the channel factory.
            Dim factory = binding.BuildChannelFactory(Of IRequestChannel)(New BindingParameterCollection())
            'Open the channel factory.
            factory.Open()

            'Step3: Use the channel factory to create a channel.
            Dim channel = factory.CreateChannel(New EndpointAddress("http://localhost:8080/channelapp"))
            channel.Open()

            'Step4: Create a message.
            Dim requestmessage = Message.CreateMessage(binding.MessageVersion, _
                                                       "http://contoso.com/someaction", _
                                                       "This is the body data")
            'Send message.
            Dim replymessage = channel.Request(requestmessage)
            Console.WriteLine("Reply message received")
            Console.WriteLine("Reply action: {0}", replymessage.Headers.Action)
            Dim data = replymessage.GetBody(Of String)()
            Console.WriteLine("Reply content: {0}", data)

            'Step5: Do not forget to close the message.
            replymessage.Close()
            'Do not forget to close the channel.
            channel.Close()
            'Do not forget to close the factory.
            factory.Close()
        End Sub

        Public Shared Sub Main()

            Console.WriteLine("Press [ENTER] when service is ready")
            Console.ReadLine()
            RunClient()
            Console.WriteLine("Press [ENTER] to exit")
            Console.ReadLine()

        End Sub
    End Class
End Namespace