Bagikan melalui


Pemrograman Tingkat Saluran Layanan

Topik ini menjelaskan cara menulis aplikasi layanan Windows Communication Foundation (WCF) tanpa menggunakan System.ServiceModel.ServiceHost dan model objek terkait.

Menerima Pesan

Agar siap menerima dan memproses pesan, langkah-langkah berikut diperlukan:

  1. Membuat pengikatan.

  2. Membuat pendengar saluran.

  3. Membuka pendengar saluran.

  4. Membaca permintaan dan mengirim balasan.

  5. Menutup semua objek saluran.

Membuat Pengikatan

Langkah pertama dalam mendengarkan dan menerima pesan adalah membuat pengikatan. WCF dikirim dengan beberapa pengikatan bawaan atau yang disediakan sistem yang dapat digunakan langsung dengan membuat instans salah satunya. Selain itu, Anda juga dapat membuat pengikatan kustom Anda sendiri dengan membuat instans kelas CustomBinding yang merupakan apa yang dilakukan kode dalam daftar 1.

Contoh kode di bawah ini membuat instans System.ServiceModel.Channels.CustomBinding dan menambahkan System.ServiceModel.Channels.HttpTransportBindingElement ke koleksi Elemennya yang merupakan kumpulan elemen pengikatan yang digunakan untuk membuat tumpukan saluran. Dalam contoh ini, karena koleksi elemen hanya memiliki HttpTransportBindingElement, tumpukan saluran yang dihasilkan hanya memiliki saluran transportasi HTTP.

Membuat ChannelListener

Setelah membuat pengikatan, kami memanggil Binding.BuildChannelListener untuk membuat pendengar saluran yang mana parameter jenis merupakan bentuk saluran yang akan dibuat. Dalam contoh ini, kami menggunakan System.ServiceModel.Channels.IReplyChannel karena kami ingin mendengarkan pesan masuk dalam pola pertukaran pesan permintaan/balasan.

IReplyChannel digunakan untuk menerima pesan permintaan dan mengirim kembali pesan balasan. Memanggil IReplyChannel.ReceiveRequest mengembalikan System.ServiceModel.Channels.IRequestChannel, yang dapat digunakan untuk menerima pesan permintaan dan mengirim kembali pesan balasan.

Saat membuat pendengar, kami meneruskan alamat jaringan yang didengarkannya, dalam hal ini http://localhost:8080/channelapp. Secara umum, setiap saluran transportasi mendukung satu atau mungkin beberapa skema alamat, misalnya, transportasi HTTP mendukung skema http dan https.

Kami juga meneruskan System.ServiceModel.Channels.BindingParameterCollection kosong saat membuat pendengar. Parameter pengikatan adalah mekanisme untuk meneruskan parameter yang mengontrol cara pendengar harus dibuat. Dalam contoh kami, kami tidak menggunakan parameter seperti itu sehingga melewati koleksi kosong.

Mendengarkan Pesan Masuk

Kemudian, kami memanggil ICommunicationObject.Open di pendengar dan mulai menerima saluran. Perilaku IChannelListener<TChannel>.AcceptChannel tergantung pada apakah transportasi berorientasi koneksi atau tanpa koneksi. Untuk transportasi berorientasi koneksi, AcceptChannel memblokir hingga permintaan koneksi baru masuk yang mana mengembalikan saluran baru yang mewakili koneksi baru tersebut. Untuk transportasi tanpa koneksi, seperti HTTP, AcceptChannel segera kembali dengan satu dan satu-satunya saluran yang dibuat pendengar transportasi.

Dalam contoh ini, pendengar mengembalikan saluran yang mengimplementasikan IReplyChannel. Untuk menerima pesan di saluran ini, pertama-tama kami memanggil ICommunicationObject.Open untuk menempatkannya dalam keadaan siap untuk komunikasi. Kemudian, kami memanggil ReceiveRequest yang memblokir hingga pesan tiba.

Membaca Permintaan dan Mengirim Balasan

Saat ReceiveRequest mengembalikan RequestContext, kami mendapatkan pesan yang diterima menggunakan properti RequestMessage. Kami menuliskan tindakan pesan dan konten isi, (yang kami asumsikan adalah string).

Untuk mengirim balasan, kami membuat pesan balasan baru dalam hal ini meneruskan kembali data string yang diterima dalam permintaan. Kemudian, kami memanggil Reply untuk mengirim pesan balasan.

Menutup Objek

Untuk menghindari kebocoran sumber daya, sangat penting untuk menutup objek yang digunakan dalam komunikasi saat tidak lagi diperlukan. Dalam contoh ini, kami menutup pesan permintaan, konteks permintaan, saluran, dan pendengar.

Contoh kode berikut menunjukkan layanan dasar yang mana pendengar saluran hanya menerima satu pesan. Layanan nyata terus menerima saluran dan menerima pesan hingga layanan keluar.

using System;
using System.ServiceModel.Channels;
namespace ProgrammingChannels
{
class Service
{
static void RunService()
{
    //Step1: Create a custom binding with just TCP.
    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 listener.
    IChannelListener<IReplyChannel> listener =
          binding.BuildChannelListener<IReplyChannel>(
             new Uri("http://localhost:8080/channelapp"),
           new BindingParameterCollection());

    //Step3: Listening for messages.
    listener.Open();
    Console.WriteLine(
           "Listening for incoming channel connections");
    //Wait for and accept incoming connections.
    IReplyChannel channel = listener.AcceptChannel();
    Console.WriteLine("Channel accepted. Listening for messages");
    //Open the accepted channel.
    channel.Open();
    //Wait for and receive a message from the channel.
    RequestContext request= channel.ReceiveRequest();
    //Step4: Reading the request message.
    Message message = request.RequestMessage;
    Console.WriteLine("Message received");
    Console.WriteLine("Message action: {0}",
                          message.Headers.Action);
    string data=message.GetBody<string>();
    Console.WriteLine("Message content: {0}",data);
    //Send a reply.
    Message replymessage=Message.CreateMessage(
        binding.MessageVersion,
        "http://contoso.com/someotheraction",
         data);
    request.Reply(replymessage);
    //Step5: Closing objects.
    //Do not forget to close the message.
    message.Close();
    //Do not forget to close RequestContext.
    request.Close();
    //Do not forget to close channels.
    channel.Close();
    //Do not forget to close listeners.
    listener.Close();
}
public static void Main()
{
    Service.RunService();
    Console.WriteLine("Press enter to exit");
    Console.ReadLine();
}
}
}
Imports System.ServiceModel.Channels

Namespace ProgrammingChannels
    Friend Class Service

        Private Shared Sub RunService()

            'Step1: Create a custom binding with just TCP.
            Dim bindingElements(1) As BindingElement = {New TextMessageEncodingBindingElement(), _
                                                        New HttpTransportBindingElement()}

            Dim binding As New CustomBinding(bindingElements)

            'Step2: Use the binding to build the channel listener.         
            Dim listener = binding.BuildChannelListener(Of IReplyChannel)(New Uri("http://localhost:8080/channelapp"), _
                                                                          New BindingParameterCollection())

            'Step3: Listening for messages.
            listener.Open()
            Console.WriteLine("Listening for incoming channel connections")

            'Wait for and accept incoming connections.
            Dim channel = listener.AcceptChannel()
            Console.WriteLine("Channel accepted. Listening for messages")

            'Open the accepted channel.
            channel.Open()

            'Wait for and receive a message from the channel.
            Dim request = channel.ReceiveRequest()

            'Step4: Reading the request message.
            Dim message = request.RequestMessage
            Console.WriteLine("Message received")
            Console.WriteLine("Message action: {0}", message.Headers.Action)
            Dim data = message.GetBody(Of String)()
            Console.WriteLine("Message content: {0}", data)
            'Send a reply.
            Dim replymessage = Message.CreateMessage(binding.MessageVersion, _
                                                     "http://contoso.com/someotheraction", data)
            request.Reply(replymessage)
            'Step5: Closing objects.
            'Do not forget to close the message.
            message.Close()
            'Do not forget to close RequestContext.
            request.Close()
            'Do not forget to close channels.
            channel.Close()
            'Do not forget to close listeners.
            listener.Close()
        End Sub

        Public Shared Sub Main()

            Service.RunService()
            Console.WriteLine("Press enter to exit")
            Console.ReadLine()

        End Sub

    End Class
End Namespace