Bagikan melalui


Memilih Pola Pertukaran Pesan

Langkah pertama dalam menulis transportasi kustom adalah memutuskan pola pertukaran pesan (atau MEP) yang dibutuhkan untuk saluran yang Anda kembangkan. Topik ini menjelaskan opsi yang tersedia dan membahas berbagai persyaratan. Ini adalah tugas pertama dalam daftar tugas pengembangan saluran yang dijelaskan dalam Mengembangkan Saluran.

Enam Pola Pertukaran Pesan

Ada tiga MEP yang dapat dipilih:

  • Datagram (IInputChannel dan IOutputChannel)

    Saat menggunakan MEP datagram, klien mengirimkan pesan menggunakan pertukaran fire and forget. Pertukaran fire and forget adalah pertukaran yang memerlukan konfirmasi out-of-band atas keberhasilan pengiriman. Pesan mungkin hilang saat transit dan tidak pernah mencapai layanan. Jika operasi pengiriman berhasil diselesaikan di pihak klien, operasi ini tidak menjamin bahwa titik akhir jarak jauh telah menerima pesan. Datagram adalah blok bangunan mendasar untuk olahpesan, karena Anda dapat membangun protokol Anda sendiri di blok tersebut—termasuk protokol yang andal dan protokol yang aman. Saluran datagram klien mengimplementasikan antarmuka IOutputChannel dan saluran datagram layanan mengimplementasikan antarmuka IInputChannel.

  • Permintaan-Respons (IRequestChannel dan IReplyChannel)

    Dalam MEP ini, pesan dikirim, dan balasan diterima. Pola terdiri dari pasangan permintaan-respons. Contoh panggilan permintaan-respons adalah panggilan prosedur jarak jauh (RPC) dan permintaan GET browser. Pola ini juga dikenal sebagai setengah dupleks. Dalam MEP ini, saluran klien menerapkan IRequestChannel dan saluran layanan menerapkan IReplyChannel.

  • Dupleks (IDuplexChannel)

    MEP dupleks memungkinkan jumlah pesan arbitrer untuk dikirim oleh klien dan diterima dalam urutan apa pun. MEP dupleks seperti percakapan telepon, tempat setiap kata yang diucapkan adalah pesan. Karena kedua belah pihak dapat mengirim dan menerima dalam MEP ini, antarmuka yang diterapkan oleh klien dan saluran layanan adalah IDuplexChannel.

Flowchart showing the three basic message exchange patterns
Tiga pola pertukaran pesan dasar. Atas ke bawah: datagram, permintaan-respons, dan dupleks.

Masing-masing MEP ini juga dapat mendukung sesi. Sesi (dan implementasi System.ServiceModel.Channels.ISessionChannel<TSession> jenis System.ServiceModel.Channels.ISession) menghubungkan semua pesan yang dikirim dan diterima di saluran. Pola permintaan-respons adalah sesi dua pesan yang berdiri sendiri, karena permintaan dan balasan berkorelasi. Sebaliknya, pola permintaan-respons yang mendukung sesi menyiratkan bahwa semua pasangan permintaan/respons pada saluran tersebut berkorelasi satu sama lain. Hal ini memberi Anda enam MEP untuk dipilih:

  • Datagram

  • Permintaan-respons

  • Dupleks

  • Datagram dengan sesi

  • Permintaan-respons dengan sesi

  • Dupleks dengan sesi

Catatan

Untuk transportasi UDP, satu-satunya MEP yang didukung adalah datagram, karena UDP secara inheren merupakan protokol fire and forget.

Sesi dan Saluran Sesi

Dalam dunia jaringan, terdapat protokol berorientasi koneksi (misalnya, TCP) dan protokol tanpa koneksi (misalnya, UDP). WCF menggunakan istilah sesi untuk merujuk pada abstraksi logis seperti koneksi. Protokol WCF sesi serupa dengan protokol jaringan berorientasi koneksi dan protokol WCF tanpa sesi serupa dengan protokol jaringan tanpa koneksi.

Dalam model objek saluran, setiap sesi logis bermanifestasi sebagai instans saluran sesi. Oleh karena itu, setiap sesi baru yang dibuat oleh klien dan diterima oleh layanan sesuai dengan saluran sesi yang baru di setiap sisi. Bagian atas diagram berikut menunjukkan struktur saluran tanpa sesi dan bagian akhir diagram tersebut menunjukkan struktur saluran sesi.

Flowchart showing the structure of sessionless and sessionful channels

Klien membuat saluran sesi baru dan mengirimkan pesan. Di sisi layanan, pendengar saluran menerima dan mendeteksi bahwa pesan ini adalah miliki sesi yang baru dan membuat saluran sesi baru serta menyerahkannya ke aplikasi (sebagai respons terhadap aplikasi yang memanggil AcceptChannel di pendengar saluran). Kemudian aplikasi menerima pesan ini serta semua pesan berikutnya yang dikirim di sesi yang sama melalui saluran sesi yang sama.

Klien lain (atau klien yang sama) membuat sesi baru dan mengirim pesan. Pendengar saluran mendeteksi bahwa pesan ini berada di sesi baru dan membuat saluran sesi baru, proses yang sama terus berulang.

Tanpa sesi, tidak ada korelasi antara saluran dan sesi. Oleh karena itu, pendengar saluran hanya membuat satu saluran di mana semua pesan yang diterima dikirim ke aplikasi. Pengurutan pesan juga tidak ada karena tidak ada sesi untuk mempertahankan urutan pesan. Bagian atas grafik sebelumnya menggambarkan pertukaran pesan tanpa sesi.

Memulai dan Mengakhiri Sesi

Sesi dimulai di klien hanya dengan membuat saluran sesi baru. Sesi dimulai pada layanan ketika layanan tersebut menerima pesan yang dikirim dalam sesi baru. Demikian juga, sesi diakhiri dengan menutup atau membatalkan saluran sesi.

Pengecualian untuk ini adalah IDuplexSessionChannel yang digunakan untuk mengirim dan menerima pesan dalam pola komunikasi dupleks dan sesi. Ada kemungkinan bahwa suatu sisi ingin berhenti mengirim pesan tetapi terus menerimanya, oleh karena itu, ketika menggunakan IDuplexSessionChannel ada mekanisme yang memungkinkan Anda menutup sesi output yang menunjukkan Anda tidak akan mengirim pesan lagi tetapi menjaga sesi input tetap terbuka memungkinkan Anda untuk terus menerima pesan.

Secara umum, sesi ditutup di sisi keluar, bukan di sisi masuk. Artinya, saluran output sesi dapat ditutup, sehingga mengakhiri sesi dengan bersih. Menutup saluran output sesi menyebabkan saluran input sesi yang sesuai mengembalikan null ke aplikasi yang memanggil IInputChannel.Receive di IDuplexSessionChannel.

Namun, saluran input sesi tidak boleh ditutup kecuali IInputChannel.Receive pada IDuplexSessionChannel mengembalikan null, menunjukkan bahwa sesi telah ditutup. Jika IInputChannel.Receive pada IDuplexSessionChannel belum mengembalikan null, menutup saluran input sesi dapat melemparkan pengecualian karena mungkin menerima pesan yang tidak terduga saat menutup. Jika penerima ingin menghentikan sesi sebelum pengirim melakukannya, penerima harus memanggil Abort di saluran input yang akan mengakhiri sesi secara mendadak.

Menulis Saluran Sesi

Sebagai penulis saluran sesi, ada beberapa hal yang harus dilakukan saluran Anda untuk menyediakan sesi. Di sisi pengiriman, saluran Anda harus:

  • Untuk setiap saluran, membuat sesi baru dan mengaitkannya dengan id sesi baru yang merupakan string unik. Atau dapatkan sesi baru dari saluran sesi di bawah Anda dalam tumpukan.

  • Untuk setiap pesan yang dikirim menggunakan saluran ini, jika saluran Anda membuat sesi (dibandingkan dengan mendapatkannya dari lapisan di bawah Anda), Anda perlu mengaitkan pesan dengan sesi. Untuk saluran protokol, hal ini biasanya dilakukan dengan menambahkan header SOAP. Untuk saluran transportasi, hal ini biasanya dilakukan dengan membuat koneksi transportasi batu atau dengan menambahkan informasi ke protokol pembingkaian.

  • Untuk setiap pesan yang dikirim menggunakan saluran ini, Anda perlu memberikan jaminan pengiriman yang disebutkan sebelumnya. Jika Anda mengandalkan saluran di bawah Anda untuk memberikan sesi, saluran tersebut juga akan memberi jaminan pengiriman. Jika Anda menyediakan sesi sendiri, Anda perlu menerapkan jaminan tersebut sebagai bagian dari protokol Anda. Secara umum, jika Anda menulis saluran protokol yang mengasumsikan WCF di kedua sisi, Anda mungkin perlu transportasi TCP atau saluran Olahpesan yang Andal dan mengandalkan salah satu untuk menyediakan sesi.

  • Saat ICommunicationObject.Close dipanggil di saluran Anda, lakukan pekerjaan yang diperlukan untuk menutup sesi menggunakan batas waktu yang ditentukan atau default. Pekerjaan ini bisa sesederhana menelepon Close di saluran bawah Anda (jika Anda baru saja mendapatkan sesi darinya) atau mengirim pesan SOAP khusus atau menutup koneksi transportasi.

  • Saat Abort dipanggil di saluran Anda, hentikan sesi secara mendadak tanpa melakukan I/O. Hal ini dapat berarti tidak melakukan apa-apa atau mungkin melibatkan pembatalan koneksi jaringan atau beberapa sumber daya lainnya.

Di sisi penerima, saluran Anda perlu:

  • Untuk setiap pesan masuk, pendengar saluran harus mendeteksi sesi pesan tersebut. Jika ini merupakan pesan pertama dalam sesi, pendengar saluran harus membuat saluran baru dan mengembalikannya dari panggilan ke IChannelListener<TChannel>.AcceptChannel. Jika tidak, pendengar saluran harus menemukan saluran yang ada yang sesuai dengan sesi dan menyampaikan pesan melalui saluran tersebut.

  • Jika saluran Anda memberikan sesi (bersama dengan jaminan pengiriman yang diperlukan), sisi penerima mungkin perlu melakukan beberapa tindakan seperti mengurutkan ulang pesan atau mengirim pengakuan.

  • Saat Close dipanggil di saluran Anda, lakukan pekerjaan yang diperlukan untuk menutup sesi, baik batas waktu yang ditentukan atau default. Hal ini dapat mengakibatkan pengecualian jika saluran menerima pesan saat menunggu batas waktu tutup untuk kedaluwarsa. Itu karena saluran akan berada dalam status Penutupan ketika menerima pesan, sehingga akan ia lemparkan.

  • Saat Abort dipanggil di saluran Anda, hentikan sesi secara mendadak tanpa melakukan I/O. Sekali lagi, hal ini dapat berarti tidak melakukan apa-apa atau mungkin melibatkan pembatalan koneksi jaringan atau beberapa sumber daya lainnya.

Lihat juga