Gambaran Umum Lapisan Saluran

Lapisan Saluran menyediakan abstraksi saluran transportasi serta pesan yang dikirim di saluran. Ini juga termasuk fungsi untuk serialisasi jenis data C ke dan dari struktur SOAP. Lapisan Saluran memungkinkan kontrol penuh komunikasi melalui pesan yang terdiri dari data yang dikirim atau diterima dan berisi isi dan header, dan saluran yang mengabstraksi protokol pertukaran pesan dan menyediakan properti untuk menyesuaikan pengaturan.

Pesan

Pesan adalah objek yang merangkum data jaringan — khususnya, data yang dikirimkan atau diterima melalui jaringan. Struktur pesan didefinisikan oleh SOAP, dengan sekumpulan header diskrit dan isi pesan. Header ditempatkan dalam buffer memori, dan isi pesan dibaca atau ditulis menggunakan API stream.

Diagram showing the header and body of a message.

Meskipun model data pesan selalu merupakan model data XML, format kawat aktual fleksibel. Sebelum pesan dikirimkan, pesan dikodekan menggunakan pengodean tertentu (seperti Teks, Biner, atau MTOM). Lihat WS_ENCODING untuk informasi selengkapnya tentang pengodean.

Diagram showing several message encoding formats.

Saluran

Saluran adalah objek yang digunakan untuk mengirim dan menerima pesan di jaringan antara dua titik akhir atau lebih.

Saluran memiliki data terkait yang menjelaskan cara mengatasi pesan saat dikirim. Mengirim pesan di saluran seperti menempatkannya di chute - saluran menyertakan informasi di mana pesan harus pergi dan cara mendapatkannya di sana.

Diagram showing channels for messages.

Saluran dikategorikan ke dalam jenis saluran. Jenis saluran menentukan pesan arah mana yang dapat mengalir. Jenis saluran juga mengidentifikasi apakah saluran penuh sesi, atau tanpa sesi. Sesi didefinisikan sebagai cara abstrak untuk menghubungkan pesan antara dua pihak atau lebih. Contoh saluran sesi adalah saluran TCP, yang menggunakan koneksi TCP sebagai implementasi sesi konkret. Contoh saluran tanpa sesi adalah UDP, yang tidak memiliki mekanisme sesi yang mendasar. Meskipun HTTP memang memiliki koneksi TCP yang mendasar, fakta ini tidak secara langsung diekspos melalui API ini dan oleh karena itu HTTP juga dianggap sebagai saluran tanpa sesi.

Diagram showing sessionful and sessionless channel types.

Meskipun jenis saluran menjelaskan arah dan informasi sesi untuk saluran, mereka tidak menentukan bagaimana saluran diimplementasikan. Protokol apa yang harus digunakan saluran? Seberapa keras saluran harus mencoba mengirimkan pesan? Keamanan seperti apa yang digunakan? Apakah singlecast atau multicast? Pengaturan ini disebut sebagai "pengikatan" saluran. Pengikatan terdiri dari yang berikut:

Diagram showing a list of channel properties.

Listener

Untuk mulai berkomunikasi, klien membuat objek Saluran. Tetapi bagaimana layanan mendapatkan objek Channel-nya? Ini melakukannya dengan membuat Listener. Membuat pendengar memerlukan informasi pengikatan yang sama yang diperlukan untuk membuat saluran. Setelah Listener dibuat, aplikasi dapat Menerima Saluran dari Listener. Karena aplikasi mungkin tertinggal dalam menerima saluran, pendengar biasanya menyimpan antrean saluran yang siap menerima (hingga beberapa kuota).

Diagram showing channels in the Listener queue.

Memulai Komunikasi (klien)

Untuk memulai komunikasi pada klien, gunakan urutan berikut.

WsCreateChannel
for each address being sent to
{
    WsOpenChannel           // open channel to address
    // send and/or receive messages
    WsCloseChannel          // close channel
    WsResetChannel?         // reset if opening again
}
WsFreeChannel

Menerima Komunikasi (server)

Untuk menerima komunikasi masuk di server, gunakan urutan berikut.

WsCreateListener
WsOpenListener
for each channel being accepted (can be done in parallel)
{
    WsCreateChannelForListener
    for each accept
    {
        WsAcceptChannel     // accept the channel
        // send and/or receive messages
        WsCloseChannel      // close the channel
        WsResetChannel?     // reset if accepting again
    }
    WsFreeChannel
}
WsCloseListener
WsFreeListener

Mengirim Pesan (klien atau server)

Untuk mengirim pesan, gunakan urutan berikut.

WsCreateMessageForChannel
for each message being sent
{
    WsSendMessage       // send message
    WsResetMessage?     // reset if sending another message
}
WsFreeMessage

Fungsi WsSendMessage tidak memungkinkan streaming, dan mengasumsikan bahwa isinya hanya berisi satu elemen. Untuk menghindari batasan ini, gunakan urutan berikut alih-alih WsSendMessage.

WsInitializeMessage     // initialize message to WS_BLANK_MESSAGE
WsSetHeader             // serialize action header into header buffer
WsAddressMessage?       // optionally address message
for each application defined header
{
    WsAddCustomHeader   // serialize application-defined headers into header buffer
}
WsWriteMessageStart     // write out the headers of the message
for each element of the body
{
    WsWriteBody         // serialize the element of the body
    WsFlushBody?        // optionally flush the body
}
WsWriteMessageEnd       // write the end of the message

Fungsi WsWriteBody menggunakan serialisasi untuk menulis elemen isi. Untuk menulis data langsung ke XML Writer, gunakan urutan berikut alih-alih WsWriteBody.

WS_MESSAGE_PROPERTY_BODY_WRITER     // get the writer used to write the body
WsWriteStartElement
// use the writer functions to write the body
WsWriteEndElement
// optionally flush the body
WsFlushBody?        

Fungsi WsAddCustomHeader menggunakan serialisasi untuk mengatur header ke buffer header pesan. Untuk menggunakan XML Writer untuk menulis header, gunakan urutan berikut alih-alih WsAddCustomHeader.

WS_MESSAGE_PROPERTY_HEADER_BUFFER   // get the header buffer 
WsCreateWriter                      // create an xml writer
WsSetOutputToBuffer                 // specify output of writer should go to buffer
WsMoveWriter*                       // move to inside envelope header element
WsWriteStartElement                 // write application header start element
// use the writer functions to write the header 
WsWriteEndElement                   // write appilcation header end element

Menerima Pesan (klien atau server)

Untuk menerima pesan, gunakan urutan berikut.

WsCreateMessageForChannel
for each message being received
{
    WsReceiveMessage            // receive a message
    WsGetHeader*                // optionally access standard headers such as To or Action
    WsResetMessage              // reset if reading another message
}
WsFreeMessage

Fungsi WsReceiveMessage tidak memungkinkan streaming, dan mengasumsikan bahwa isi hanya berisi satu elemen, dan bahwa jenis pesan (tindakan dan skema isi) diketahui di depan. Untuk menghindari batasan ini, gunakan urutan berikut alih-alih WsReceiveMessage.

WsReadMessageStart              // read all headers into header buffer
for each standard header
{
    WsGetHeader                 // deserialize standard header such as To or Action
}
for each application defined header
{
    WsGetCustomHeader           // deserialize application defined header
}
for each element of the body
{
    WsFillBody?                 // optionally fill the body
    WsReadBody                  // deserialize element of body
}
WsReadMessageEnd                // read end of message

Fungsi WsReadBody menggunakan serialisasi untuk membaca elemen isi. Untuk membaca data langsung dari Pembaca XML, gunakan urutan berikut alih-alih WsReadBody.

WS_MESSAGE_PROPERTY_BODY_READER     // get the reader used to read the body
WsFillBody?                         // optionally fill the body
WsReadToStartElement                // read up to the body element
WsReadStartElement                  // consume the start of the body element
// use the read functions to read the contents of the body element
WsReadEndElement                    // consume the end of the body element

Fungsi WsGetCustomHeader menggunakan serialisasi untuk mendapatkan header dari buffer header pesan. Untuk menggunakan Pembaca XML untuk membaca header, gunakan urutan berikut alih-alih WsGetCustomHeader.

WS_MESSAGE_PROPERTY_HEADER_BUFFER   // get the header buffer 
WsCreateReader                      // create an xml reader
WsSetInputToBuffer                  // specify input of reader should be buffer
WsMoveReader*                       // move to inside header element
while looking for header to read
{
    WsReadToStartElement            // see if the header matches the application header
    if header matched
    {
        WsGetHeaderAttributes?      // get the standard header attributes
        WsReadStartElement          // consume the start of the header element
        // use the read functions to read the contents of the header element
        WsReadEndElement            // consume the end of the header element
    }
    else
    {
        WsSkipNode                  // skip the header element
    }
}                

Minta Balasan (klien)

Melakukan balasan permintaan pada klien dapat dilakukan dengan urutan berikut.

WsCreateMessageForChannel               // create request message 
WsCreateMessageForChannel               // create reply message 
for each request reply
{
    WsRequestReply                      // send request, receive reply
    WsResetMessage?                     // reset request message (if repeating)
    WsResetMessage?                     // reset reply message (if repeating)
}
WsFreeMessage                           // free request message
WsFreeMessage                           // free reply message

Fungsi WsRequestReply mengasumsikan satu elemen untuk isi permintaan dan pesan balasan, dan bahwa jenis pesan (tindakan dan skema isi) diketahui di depan. Untuk menghindari batasan ini, permintaan dan pesan balasan dapat dikirim secara manual, seperti yang ditunjukkan dalam urutan berikut. Urutan ini cocok dengan urutan sebelumnya untuk mengirim dan menerima pesan, kecuali jika dicatat.

WsInitializeMessage     // initialize message to WS_BLANK_MESSAGE
WsSetHeader             // serialize action header into header buffer
WsAddressMessage?       // optionally address message

// the following block is specific to sending a request
{
    generate a unique MessageID for request
    WsSetHeader         // set the message ID            
}

for each application defined header
{
    WsAddCustomHeader   // serialize application-defined headers into header buffer
}
WsWriteMessageStart     // write out the headers of the message
for each element of the body
{
    WsWriteBody         // serialize the element of the body
    WsFlushBody?        // optionally flush the body
}
WsWriteMessageEnd       // write the end of the message

WsReadMessageStart      // read all headers into header buffer

// the following is specific to receiving a reply
{
    WsGetHeader         // deserialize RelatesTo ID of reply
    verify request MessageID is equal to RelatesTo ID
}

for each standard header
{
    WsGetHeader         // deserialize standard header such as To or Action
}
for each application defined header
{
    WsGetCustomHeader   // deserialize application defined header
}
for each element of the body
{
    WsFillBody?         // optionally fill the body
    WsReadBody          // deserialize element of body
}
WsReadMessageEnd        // read end of message                

Minta Balasan (server)

Untuk menerima pesan permintaan di server, gunakan urutan yang sama seperti yang diuraikan di bagian sebelumnya saat menerima pesan.

Untuk mengirim pesan balasan atau kesalahan, gunakan urutan berikut.

WsCreateMessageForChannel
for each reply being sent
{
    WsSendReplyMessage | WsSendFaultMessageForError  // send reply or fault message
    WsResetMessage?     // reset if sending another message
}
WsFreeMessage

Fungsi WsSendReplyMessage mengasumsikan satu elemen dalam isi dan tidak memungkinkan streaming. Untuk menghindari batasan ini, gunakan urutan berikut. Ini sama dengan urutan sebelumnya untuk mengirim pesan, tetapi menggunakan WS_REPLY_MESSAGE alih-alih WS_BLANK_MESSAGE saat menginisialisasi.

// the following block is specific to sending a reply
{
    WsInitializeMessage // initialize message to WS_REPLY_MESSAGE
}
WsSetHeader             // serialize action header into header buffer                                
WsAddressMessage?       // optionally address message
for each application defined header
{
    WsAddCustomHeader   // serialize application-defined headers into header buffer
}
WsWriteMessageStart     // write out the headers of the message
for each element of the body
{
    WsWriteBody         // serialize the element of the body
    WsFlushBody?        // optionally flush the body
}
WsWriteMessageEnd       // write the end of the message

Pola Exchange Pesan

WS_CHANNEL_TYPE menentukan pola pertukaran pesan yang mungkin untuk saluran tertentu. Jenis yang didukung, bervariasi sesuai dengan pengikatan, sebagai berikut:

Perulangan Pesan

Untuk setiap pola pertukaran pesan, ada "perulangan" tertentu yang dapat digunakan untuk mengirim atau menerima pesan. Perulangan menjelaskan urutan hukum operasi yang diperlukan untuk mengirim/menerima beberapa pesan. Perulangan digambarkan di bawah ini sebagai produksi tata bahasa. Istilah 'akhir' adalah penerimaan tempat WS_S_END dikembalikan (Lihat Nilai Pengembalian Windows Web Services), yang menunjukkan tidak ada lagi pesan yang tersedia di saluran. Produksi paralel menentukan bahwa untuk paralel(x & y) operasi x dapat dilakukan bersamaan dengan y.

Perulangan berikut digunakan pada klien:

client-loop := client-request-loop | client-duplex-session-loop | client-duplex-loop
client-request-loop := open (send (receive | end))* close // WS_CHANNEL_TYPE_REQUEST
client-duplex-session-loop := open parallel(send* & receive*) parallel(send? & end*) close // WS_CHANNEL_TYPE_DUPLEX_SESSION
client-duplex-loop := open parallel(send & receive)* close // WS_CHANNEL_TYPE_DUPLEX

Perulangan berikut digunakan pada server:

server-loop: server-reply-loop | server-duplex-session-loop | server-duplex-loop
server-reply-loop := accept receive end* send? end* close // WS_CHANNEL_TYPE_REPLY
server-duplex-session-loop := accept parallel(send* & receive*) parallel(send* & end*) close // WS_CHANNEL_TYPE_DUPLEX_SESSION
server-input-loop := accept receive end* close // WS_CHANNEL_TYPE_INPUT

Menggunakan WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING di server memerlukan penerimaan yang berhasil sebelum pengiriman diizinkan bahkan dengan saluran jenis WS_CHANNEL_TYPE_DUPLEX_SESSION. Setelah penerimaan pertama. perulangan reguler berlaku.

Perhatikan bahwa saluran jenis WS_CHANNEL_TYPE_REQUEST dan WS_CHANNEL_TYPE_REPLY dapat digunakan untuk mengirim dan menerima pesan satu arah (serta pola balasan permintaan standar). Hal ini dilakukan dengan menutup saluran balasan tanpa mengirim balasan. Dalam hal ini, tidak akan ada balasan yang diterima di saluran permintaan. Nilai pengembalian WS_S_END Menggunakan WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING di server memerlukan penerimaan yang berhasil sebelum pengiriman diizinkan bahkan dengan saluran jenis WS_CHANNEL_TYPE_DUPLEX_SESSION. Setelah pertama menerima perulangan reguler berlaku.

akan dikembalikan, menunjukkan tidak ada pesan yang tersedia.

Perulangan klien atau server dapat dilakukan secara paralel satu sama lain dengan menggunakan beberapa instans saluran.

parallel-client: parallel(client-loop(channel1) & client-loop(channel2) & ...)
parallel-server: parallel(server-loop(channel1) & server-loop(channel2) & ...)

Pemfilteran Pesan

Saluran server dapat memfilter pesan yang diterima yang tidak ditujukan untuk aplikasi, seperti pesan yang menetapkan konteks keamanan. Dalam hal ini WS_S_END akan dikembalikan dari WsReadMessageStart dan tidak ada pesan aplikasi yang akan tersedia di saluran tersebut. Namun, ini tidak memberi sinyal bahwa klien dimaksudkan untuk mengakhiri komunikasi dengan server. Pesan lainnya mungkin tersedia di saluran lain. Lihat WsShutdownSessionChannel.

Pembatalan

Fungsi WsAbortChannel digunakan untuk membatalkan IO yang tertunda untuk saluran. API ini tidak akan menunggu operasi IO selesai. Lihat diagram dan dokumentasi status WS_CHANNEL_STATE untuk WsAbortChannel untuk informasi selengkapnya.

WsAbortListener API digunakan untuk membatalkan IO yang tertunda untuk pendengar. API ini tidak akan menunggu operasi IO selesai. Membatalkan pendengar juga akan menyebabkan penerimaan yang tertunda dibatalkan. Lihat diagram status WS_LISTENER_STATE dan WsAbortListener untuk informasi selengkapnya.

TCP

WS_TCP_CHANNEL_BINDING mendukung SOAP melalui TCP. SOAP melalui spesifikasi TCP dibangun berdasarkan mekanisme .NET Framing.

Berbagi port tidak didukung dalam versi ini. Setiap pendengar yang dibuka harus menggunakan nomor port yang berbeda.

UDP

WS_UDP_CHANNEL_BINDING mendukung SOAP melalui UDP.

Ada sejumlah batasan dengan pengikatan UDP:

  • Tidak ada dukungan untuk keamanan.
  • Pesan mungkin hilang atau diduplikasi.
  • Hanya satu pengodean yang didukung: WS_ENCODING_XML_UTF8.
  • Pesan pada dasarnya dibatasi hingga 64k, dan sering kali memiliki kemungkinan yang lebih besar hilang jika ukurannya melebihi MTU jaringan.

HTTP

WS_HTTP_CHANNEL_BINDING mendukung SOAP melalui HTTP.

Untuk mengontrol header spesifik HTTP pada klien dan server, lihat WS_HTTP_MESSAGE_MAPPING.

Untuk mengirim dan menerima pesan non-SOAP di server, gunakan WS_ENCODING_RAW untuk WS_CHANNEL_PROPERTY_ENCODING.

NAMEDPIPES

WS_NAMEDPIPE_CHANNEL_BINDING mendukung SOAP melalui pipa bernama, memungkinkan komunikasi dengan layanan Windows Communication Foundation (WCF) menggunakan NetNamedPipeBinding.

Mengkorelasikan Pesan Permintaan/Balasan

Pesan Permintaan/Balasan berkorelasi dengan salah satu dari dua cara:

  • Korelasi dilakukan menggunakan saluran sebagai mekanisme korelasi. Misalnya, saat menggunakan WS_ADDRESSING_VERSION_TRANSPORT dan WS_HTTP_CHANNEL_BINDING balasan untuk pesan permintaan berkorelasi dengan permintaan dengan fakta bahwa itu adalah badan entitas respons HTTP.
  • Korelasi dilakukan menggunakan header MessageID dan RelatesTo. Mekanisme ini digunakan dengan WS_ADDRESSING_VERSION_1_0 dan WS_ADDRESSING_VERSION_0_9 (bahkan saat menggunakan WS_HTTP_CHANNEL_BINDING). Dalam hal ini, pesan permintaan menyertakan header MessageID. Pesan respons menyertakan header RelatesTo yang memiliki nilai header MessageID permintaan. Header RelatesTo memungkinkan klien untuk menghubungkan respons dengan permintaan yang dikirim.

API lapisan saluran berikut secara otomatis menggunakan mekanisme korelasi yang sesuai berdasarkan WS_ADDRESSING_VERSION saluran.

Jika API ini tidak digunakan, header dapat ditambahkan dan diakses secara manual menggunakan WsSetHeader atau WsGetHeader.

Saluran dan Listener Kustom

Jika set pengikatan saluran yang telah ditentukan sebelumnya tidak memenuhi kebutuhan aplikasi, maka implementasi saluran dan pendengar kustom dapat ditentukan dengan menentukan WS_CUSTOM_CHANNEL_BINDING saat membuat saluran atau pendengar. Implementasi aktual saluran/pendengar ditentukan sebagai serangkaian panggilan balik melalui properti WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS atau WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS. Setelah saluran atau pendengar kustom dibuat, hasilnya adalah objek WS_CHANNEL atau WS_LISTENER yang dapat digunakan dengan API yang ada.

Saluran kustom dan pendengar juga dapat digunakan dengan Proksi Layanan dan Host Layanan dengan menentukan nilai WS_CUSTOM_CHANNEL_BINDING dalam enumerasi WS_CHANNEL_BINDING dan properti WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS dan WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS saat membuat Proksi Layanan atau Host Layanan.

Keamanan

Saluran ini memungkinkan pembatasan jumlah memori yang digunakan untuk berbagai aspek operasi melalui properti seperti:

  • WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
  • WS_CHANNEL_PROPERTY_MAX_STREAMED_MESSAGE_SIZE,
  • WS_CHANNEL_PROPERTY_MAX_STREAMED_START_SIZE,
  • WS_CHANNEL_PROPERTY_MAX_HTTP_REQUEST_HEADERS_BUFFER_SIZE,
  • WS_CHANNEL_PROPERTY_MAX_SESSION_DICTIONARY_SIZE.

Properti ini memiliki nilai default yang konservatif dan aman untuk sebagian besar skenario. Nilai default dan modifikasi apa pun harus dievaluasi dengan hati-hati terhadap vektor serangan potensial yang dapat menyebabkan penolakan layanan oleh pengguna jarak jauh.

Saluran ini memungkinkan pengaturan nilai batas waktu untuk berbagai aspek operasi melalui properti seperti:

  • WS_CHANNEL_PROPERTY_CONNECT_TIMEOUT,
  • WS_CHANNEL_PROPERTY_SEND_TIMEOUT,
  • WS_CHANNEL_PROPERTY_RECEIVE_RESPONSE_TIMEOUT,
  • WS_CHANNEL_PROPERTY_RECEIVE_TIMEOUT,
  • WS_CHANNEL_PROPERTY_RESOLVE_TIMEOUT,
  • WS_CHANNEL_PROPERTY_CLOSE_TIMEOUT.

Properti ini memiliki nilai default yang konservatif dan aman untuk sebagian besar skenario. Meningkatkan nilai batas waktu meningkatkan jumlah waktu pihak jarak jauh dapat menyimpan sumber daya lokal hidup, seperti memori, soket, dan utas yang melakukan I/O sinkron. Aplikasi harus mengevaluasi nilai default dan berhati-hati saat meningkatkan batas waktu karena dapat membuka vektor serangan potensial yang dapat menyebabkan penolakan layanan dari komputer jarak jauh.

Beberapa opsi konfigurasi lain dan pertimbangan desain aplikasi yang harus dievaluasi dengan hati-hati saat menggunakan WWSAPI Channel API:

  • Saat menggunakan lapisan saluran/pendengar, terserah aplikasi untuk membuat dan menerima saluran di sisi server. Demikian pula, terserah aplikasi untuk membuat dan membuka saluran di sisi klien. Aplikasi harus menempatkan batas atas pada operasi ini karena setiap saluran mengonsumsi memori dan sumber daya terbatas lainnya seperti soket. Aplikasi harus sangat berhati-hati saat membuat saluran sebagai respons terhadap tindakan apa pun yang dipicu oleh pihak jarak jauh.
  • Terserah aplikasi untuk menulis logika untuk membuat saluran dan menerimanya. Setiap saluran menggunakan sumber daya terbatas seperti memori dan soket. Aplikasi harus memiliki batas atas pada jumlah saluran yang bersedia diterimanya, atau pihak jarak jauh dapat membuat banyak koneksi, yang mengarah ke OOM dan karenanya menolak layanan. Ini juga harus secara aktif menerima pesan dari koneksi tersebut menggunakan waktu habis yang kecil. Jika tidak ada pesan yang diterima, maka operasi akan kehabisan waktu dan koneksi harus dirilis.
  • Terserah aplikasi untuk mengirim balasan atau kesalahan dengan menginterpretasikan header SOAP ReplyTo atau FaultTo. Praktik aman adalah hanya untuk menghormati header ReplyTo atau FaultTo yang "anonim", yang berarti bahwa koneksi yang ada (TCP, HTTP) atau IP sumber (UDP) harus digunakan untuk mengirim balasan SOAP. Aplikasi harus berhati-hati saat membuat sumber daya (seperti saluran) untuk membalas alamat yang berbeda, kecuali pesan ditandatangani oleh pihak yang dapat berbicara untuk alamat tempat balasan dikirim.
  • Validasi yang dilakukan di lapisan saluran tidak ada penggantian untuk integritas data yang dicapai melalui keamanan. Aplikasi harus mengandalkan fitur keamanan WWSAPI untuk memastikan bahwa aplikasi berkomunikasi dengan entitas tepercaya, dan juga harus mengandalkan keamanan untuk memastikan integritas data.

Demikian pula, ada opsi konfigurasi pesan dan pertimbangan desain aplikasi yang harus dievaluasi dengan hati-hati saat menggunakan WWSAPI Message API:

  • Ukuran tumpukan yang digunakan untuk menyimpan header pesan dapat dikonfigurasi menggunakan properti WS_MESSAGE_PROPERTY_HEAP_PROPERTIES. Meningkatkan nilai ini memungkinkan lebih banyak memori untuk dikonsumsi oleh header pesan, yang dapat menyebabkan OOM.
  • Pengguna objek pesan harus menyadari bahwa API akses header adalah O(n) sehubungan dengan jumlah header dalam pesan, karena mereka memeriksa duplikat. Desain yang memerlukan banyak header dalam pesan dapat menyebabkan penggunaan CPU yang berlebihan.
  • Jumlah maksimum header dalam pesan dapat dikonfigurasi menggunakan properti WS_MESSAGE_PROPERTY_MAX_PROCESSED_HEADERS. Ada juga batas implisit berdasarkan ukuran tumpukan pesan. Meningkatkan kedua nilai ini memungkinkan lebih banyak header untuk hadir, yang menggabungkan waktu yang diperlukan untuk menemukan header (saat menggunakan API akses header).