Bagikan melalui


Layanan Pemrograman Channel-Level

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. Buat pengikatan.

  2. Buat pendengar saluran.

  3. Buka pendengar saluran.

  4. Baca permintaan dan kirim balasan.

  5. Tutup semua objek saluran.

Membuat Pengikatan

Langkah pertama dalam mendengarkan dan menerima pesan adalah membuat pengikatan. WCF dilengkapi dengan beberapa pengikatan bawaan atau yang disediakan oleh sistem yang dapat langsung digunakan dengan menginstansiasi 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 Elements-nya yang merupakan kumpulan elemen pengikatan yang digunakan untuk membangun tumpukan saluran. Dalam contoh ini, karena koleksi elemen hanya memiliki HttpTransportBindingElement, tumpukan saluran yang dihasilkan hanya memiliki saluran transportasi HTTP.

Membangun Pendengar Kanal

Setelah membuat pengikatan, kami memanggil Binding.BuildChannelListener untuk membangun pendengar saluran di mana parameter jenis adalah bentuk saluran yang akan dibuat. Dalam contoh ini kita menggunakan System.ServiceModel.Channels.IReplyChannel karena kita 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 bagaimana pendengar harus dibangun. Dalam contoh kami, kami tidak menggunakan parameter semacam itu, jadi kami meneruskan koleksi kosong.

Mendengarkan Pesan Masuk

Kami kemudian memanggil ICommunicationObject.Open di listener dan mulai menerima saluran. Perilaku IChannelListener<TChannel>.AcceptChannel tergantung pada apakah transportasi berorientasi koneksi atau tanpa koneksi. Untuk transportasi yang berorientasi koneksi, AcceptChannel akan memblokir sampai ada permintaan koneksi baru, kemudian mengembalikan saluran baru yang mewakili permintaan koneksi baru tersebut. Untuk transportasi tanpa koneksi, seperti HTTP, AcceptChannel segera kembali dengan saluran satu dan satu-satunya 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. Kami kemudian memanggil ReceiveRequest yang akan memblokir sampai pesan tiba.

Membaca Permintaan dan Mengirim Balasan

Ketika ReceiveRequest mengembalikan RequestContext, kami mendapatkan pesan yang diterima melalui propertinya RequestMessage. Kami menulis 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 kami terima dalam permintaan. Kami kemudian memanggil Reply untuk mengirim pesan balasan.

Penutupan Objek

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

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

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: {message.Headers.Action}");
    string data=message.GetBody<string>();
    Console.WriteLine($"Message content: {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