Udostępnij za pośrednictwem


Omówienie warstwy kanału

Warstwa kanału zapewnia abstrakcję kanału transportowego oraz komunikatów wysyłanych na kanale. Obejmuje również funkcje serializacji typów danych C do i ze struktur SOAP. Warstwa kanału umożliwia pełną kontrolę nad komunikacją za pomocą komunikatów, które składają się z danych wysyłanych lub odbieranych i zawierają treści oraz nagłówki, oraz kanałów, które abstrakcyjnie traktują protokoły wymiany wiadomości i oferują właściwości pozwalające na dostosowywanie ustawień.

Komunikat

Komunikat jest obiektem, który hermetyzuje dane sieciowe — w szczególności dane przesyłane lub odbierane przez sieć. Struktura komunikatów jest definiowana przez protokół SOAP z dyskretnym zestawem nagłówków i treścią komunikatu. Nagłówki są umieszczane w buforze pamięci, a treść komunikatu jest odczytywana lub zapisywana przy użyciu API do strumieni.

Diagram przedstawiający nagłówek i treść komunikatu.

Chociaż model danych komunikatu jest zawsze modelem danych XML, rzeczywisty format przewodu jest elastyczny. Przed przesłaniem komunikatu kodowany jest przy użyciu określonego kodowania (takiego jak Text, Binary lub MTOM). Aby uzyskać więcej informacji na temat kodowania, zobacz WS_ENCODING.

Diagram przedstawiający kilka formatów kodowania komunikatów.

Kanał

Kanał to obiekt służący do wysyłania i odbierania komunikatów w sieci między dwoma lub więcej punktami końcowymi.

Kanały mają skojarzone dane, które opisują, jak zaadresować komunikat podczas jego wysyłania. Wysyłanie komunikatu na kanale przypomina umieszczenie go w rynnie — kanał zawiera informacje, gdzie powinien trafić komunikat i jak go tam dostarczyć.

Diagram przedstawiający kanały komunikatów.

Kanały są podzielone na kategorie typów kanałów . Typ kanału określa, w którym kierunku mogą przepływać komunikaty. Typ kanału określa również, czy kanał jest stanowy, czy bezstanowy. Sesja jest definiowana jako abstrakcyjny sposób korelowania komunikatów między co najmniej dwiema stronami. Przykładem kanału z obsługą sesji jest kanał TCP, który wykorzystuje połączenie TCP jako konkretną implementację sesji. Przykładem kanału bez sesji jest UDP, który nie ma podstawowego mechanizmu sesji. Mimo że protokół HTTP ma podstawowe połączenia TCP, fakt ten nie jest bezpośrednio uwidaczniony za pośrednictwem tego interfejsu API, dlatego protokół HTTP jest również uważany za kanał bez sesji.

Diagram przedstawiający typy kanałów sesyjnych i niesesyjnych.

Chociaż rodzaje kanałów opisują informacje o kierunku i sesji dla kanału, nie określają one sposobu jego implementacji. Jakiego protokołu powinien używać kanał? Jak bardzo kanał powinien się starać, aby dostarczyć komunikat? Jakiego rodzaju zabezpieczenia są używane? Czy jest to transmisja pojedyncza czy grupowa? Te ustawienia są określane jako "wiązanie" kanału. Powiązanie składa się z następujących elementów:

Diagram przedstawiający listę właściwości kanału.

Słuchacz

Aby rozpocząć komunikację, klient tworzy obiekt Channel. Lecz jak usługa uzyskuje swój obiekt Channel? Robi to przez utworzenie odbiornika . Aby utworzyć odbiornik, wymagane są te same informacje o powiązaniu, które są niezbędne do utworzenia kanału. Po utworzeniu odbiornika aplikacja może akceptować kanały z odbiornika. Ponieważ aplikacja może znajdować się w tyle w akceptowaniu kanałów, nasłuchujący zwykle przechowują kolejkę kanałów gotowych do zaakceptowania (do pewnego limitu).

Diagram przedstawiający kanały w kolejce Listener.

Inicjowanie komunikacji (klient)

Aby zainicjować komunikację po stronie klienta, użyj następującej sekwencji.

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

Akceptowanie komunikacji serwera

Aby zaakceptować komunikację przychodzącą na serwerze, użyj następującej sekwencji.

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

Wysyłanie komunikatów (klient lub serwer)

Aby wysyłać komunikaty, użyj następującej sekwencji.

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

Funkcja WsSendMessage nie zezwala na przesyłanie strumieniowe i zakłada, że treść zawiera tylko jeden element. Aby uniknąć tych ograniczeń, użyj następującej sekwencji zamiast 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

Funkcja WsWriteBody używa serializacji do zapisywania elementów treści. Aby zapisać dane bezpośrednio do XML Writer, użyj następującej sekwencji zamiast 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?        

Funkcja WsAddCustomHeader używa serializacji do ustawiania nagłówków na bufor nagłówka komunikatu. Aby użyć modułu do zapisu XML do zapisania nagłówka, użyj następującej sekwencji zamiast 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 application header end element

Odbieranie komunikatów (klient lub serwer)

Aby odbierać komunikaty, użyj następującej sekwencji.

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

Funkcja WsReceiveMessage nie zezwala na przesyłanie strumieniowe i zakłada, że treść zawiera tylko jeden element, a typ komunikatu (akcja i schemat treści) jest znany z góry. Aby uniknąć tych ograniczeń, użyj następującej sekwencji zamiast 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

Funkcja WsReadBody używa serializacji do odczytywania elementów treści. Aby odczytać dane bezpośrednio z czytnika XML, użyj następującej sekwencji zamiast 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

Funkcje WsGetCustomHeader używają serializacji w celu pobrania nagłówków z buforu nagłówka komunikatu. Aby użyć czytnika kodu XML do odczytania nagłówka, użyj następującej sekwencji zamiast 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
    }
}                

Żądanie odpowiedzi (klienta)

Przeprowadzenie żądania-odpowiedzi po stronie klienta można wykonać przy użyciu następującej sekwencji.

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

Funkcja WsRequestReply przyjmuje jeden element treści żądania i wiadomości odpowiedzi oraz że typ wiadomości (akcja i schemat treści) są znane z góry. Aby uniknąć tych ograniczeń, żądanie i wiadomość odpowiedzi można wysłać ręcznie, jak pokazano w poniższej sekwencji. Ta sekwencja jest zgodna z wcześniejszą sekwencją wysyłania i odbierania komunikatu, z wyjątkiem przypadków zanotowania.

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                

Odpowiedź na żądanie (serwer)

Aby odebrać komunikat żądania na serwerze, użyj tej samej sekwencji, co opisane w poprzedniej sekcji dotyczącej odbierania komunikatów.

Aby wysłać odpowiedź lub komunikat o błędzie, użyj następującej sekwencji.

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

Funkcja WsSendReplyMessage przyjmuje jeden element w treści i nie zezwala na przesyłanie strumieniowe. Aby uniknąć tych ograniczeń, użyj następującej sekwencji. Jest to taka sama jak wcześniejsza sekwencja wysyłania komunikatu, ale używa WS_REPLY_MESSAGE zamiast WS_BLANK_MESSAGE podczas inicjowania.

// 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

Wzorce wymiany komunikatów

WS_CHANNEL_TYPE określa wzorzec wymiany komunikatów możliwy dla danego kanału. Obsługiwany typ różni się w zależności od powiązania w następujący sposób:

Pętle komunikatów

Dla każdego wzorca wymiany komunikatów istnieje określona pętla, która może służyć do wysyłania lub odbierania komunikatów. Pętla opisuje porządek prawny operacji niezbędnych do wysyłania/odbierania wielu komunikatów. Pętle są opisane poniżej jako produkcje gramatyczne. Termin "end" to operacja odbioru, podczas której zwracana jest WS_S_END (zobacz wartości zwracane przez usługi sieci Web systemu Windows), co wskazuje, że w kanale nie są dostępne żadne komunikaty. Produkcja równoległa określa, że dla działań równoległych (x & y) operacja x może być wykonywana jednocześnie z y.

Na kliencie są używane następujące pętle:

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

Na serwerze są używane następujące pętle:

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

Użycie WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING na serwerze wymaga pomyślnego odebrania, zanim wysyłanie będzie dozwolone, nawet w przypadku kanału typu WS_CHANNEL_TYPE_DUPLEX_SESSION. Po pierwszym odbiorze. obowiązuje zwykła pętla.

Należy pamiętać, że kanały typu WS_CHANNEL_TYPE_REQUEST i WS_CHANNEL_TYPE_REPLY mogą służyć do wysyłania i odbierania jednokierunkowych komunikatów (a także standardowego wzorca odpowiedzi na żądanie). Jest to realizowane przez zamknięcie kanału odpowiedzi bez wysyłania odpowiedzi. W takim przypadku nie będzie odpowiedzi na kanale żądania. Wartość zwracana WS_S_END Użycie WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING na serwerze wymaga pomyślnego odbioru zanim będzie możliwe wysyłanie, nawet przy użyciu kanału typu WS_CHANNEL_TYPE_DUPLEX_SESSION. Po pierwszym otrzymaniu stosuje się pętlę regularną.

zostanie zwrócony komunikat wskazujący, że komunikat nie jest dostępny.

Pętle klienta lub serwera mogą być wykonywane równolegle przy użyciu wielu instancji kanałów.

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

Filtrowanie komunikatów

Kanał serwera może filtrować odebrane komunikaty, które nie są przeznaczone dla aplikacji, takie jak komunikaty, które ustanawiają kontekst zabezpieczeń . W takim przypadku WS_S_END zostanie zwrócony z WsReadMessageStart, a na tym kanale nie będą dostępne żadne komunikaty aplikacji. Nie sygnalizuje to jednak, że klient zamierza zakończyć komunikację z serwerem. Więcej komunikatów może być dostępnych w innym kanale. Zobacz WsShutdownSessionChannel.

Anulowanie

Funkcja WsAbortChannel służy do anulowania oczekujących operacji wejścia/wyjścia dla kanału. API nie będzie czekać na ukończenie operacji wejścia/wyjścia. Zobacz diagram stanu WS_CHANNEL_STATE i dokumentację WsAbortChannel, aby uzyskać więcej informacji.

Interfejs API WsAbortListener służy do anulowania oczekujących operacji we/wy dla odbiornika. Ten interfejs API nie będzie czekał na zakończenie operacji wejścia/wyjścia. Przerwanie odbiornika spowoduje również przerwanie wszystkich oczekujących akceptacji. Aby uzyskać więcej informacji, zobacz diagram stanu WS_LISTENER_STATE i WsAbortListener.

TCP

WS_TCP_CHANNEL_BINDING obsługuje protokół SOAP za pośrednictwem protokołu TCP. Specyfikacja protokołu SOAP za pośrednictwem protokołu TCP opiera się na mechanizmie framingu platformy .NET.

Udostępnianie portów nie jest obsługiwane w tej wersji. Każdy otwarty odbiornik musi używać innego numeru portu.

UDP

WS_UDP_CHANNEL_BINDING obsługuje protokół SOAP za pośrednictwem protokołu UDP.

Istnieje wiele ograniczeń dotyczących powiązania UDP.

  • Brak obsługi zabezpieczeń.
  • Komunikaty mogą zostać utracone lub zduplikowane.
  • Obsługiwane jest tylko jedno kodowanie: WS_ENCODING_XML_UTF8.
  • Komunikaty są zasadniczo ograniczone do 64k i często mają większe szanse na utratę, jeśli rozmiar przekracza jednostki MTU sieci.

HTTP

WS_HTTP_CHANNEL_BINDING obsługuje protokół SOAP za pośrednictwem protokołu HTTP.

Aby kontrolować nagłówki specyficzne dla protokołu HTTP na kliencie i serwerze, zobacz WS_HTTP_MESSAGE_MAPPING.

Aby wysyłać i odbierać komunikaty inne niż SOAP na serwerze, użyj WS_ENCODING_RAW dla WS_CHANNEL_PROPERTY_ENCODING.

NAZWANEPIPES

WS_NAMEDPIPE_CHANNEL_BINDING obsługuje protokół SOAP przez nazwane potoki, umożliwiając komunikację z usługą Windows Communication Foundation (WCF) za pomocą NetNamedPipeBinding.

Korelowanie komunikatów żądania/odpowiedzi

Komunikaty żądań/odpowiedzi są skorelowane na jeden z dwóch sposobów:

  • Korelacja jest wykonywana przy użyciu kanału jako mechanizmu korelacji. Na przykład w przypadku używania WS_ADDRESSING_VERSION_TRANSPORT i WS_HTTP_CHANNEL_BINDING odpowiedź dla wiadomości żądania jest skorelowana z żądaniem przez fakt, że jest to treść jednostki odpowiedzi HTTP.
  • Korelacja odbywa się przy użyciu nagłówków MessageID i RelatesTo. Ten mechanizm jest stosowany z WS_ADDRESSING_VERSION_1_0 i WS_ADDRESSING_VERSION_0_9 (nawet podczas korzystania z WS_HTTP_CHANNEL_BINDING). W takim przypadku komunikat żądania zawiera nagłówek MessageID. Komunikat odpowiedzi zawiera nagłówek RelatesTo, który ma tę samą wartość co nagłówek MessageID w żądaniu. Nagłówek RelatesTo umożliwia klientowi skorelowanie odpowiedzi z wysłanym żądaniem.

Następujące API warstwy kanału automatycznie używają odpowiednich mechanizmów korelacji na podstawie WS_ADDRESSING_VERSION kanału.

Jeśli te interfejsy API nie są używane, nagłówki można dodać ręcznie i uzyskać do nich dostęp przy użyciu WsSetHeader lub WsGetHeader.

Kanały niestandardowe i odbiorniki

Jeśli wstępnie zdefiniowany zestaw powiązań kanału nie spełnia wymagań aplikacji, można zdefiniować niestandardowy kanał i implementację odbiornika, określając WS_CUSTOM_CHANNEL_BINDING podczas tworzenia kanału lub odbiornika. Rzeczywista implementacja kanału/odbiornika jest określana jako zestaw wywołań zwrotnych za pośrednictwem WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS lub WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS właściwości. Po utworzeniu niestandardowego kanału lub odbiornika wynik jest obiektem WS_CHANNEL lub WS_LISTENER, który może być używany z istniejącymi interfejsami API.

Niestandardowy kanał i odbiornik mogą być również używane z serwerem proxy usługi i hostem usługi , określając wartość WS_CUSTOM_CHANNEL_BINDING w wyliczenie WS_CHANNEL_BINDING oraz właściwości WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS i WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS podczas tworzenia serwera proxy usługi lub hosta usługi.

Bezpieczeństwo

Kanał umożliwia ograniczenie ilości pamięci używanej dla różnych aspektów operacji za pośrednictwem właściwości, takich jak:

Te właściwości mają wartości domyślne, które są konserwatywne i bezpieczne dla większości scenariuszy. Wartości domyślne i wszelkie modyfikacje powinny być dokładnie oceniane pod kątem potencjalnych wektorów ataków, które mogą spowodować odmowę usługi przez użytkownika zdalnego.

Kanał umożliwia ustawienie wartości limitu czasu dla różnych aspektów operacji za pośrednictwem właściwości, takich jak:

Te właściwości mają wartości domyślne, które są konserwatywne i bezpieczne dla większości scenariuszy. Zwiększenie wartości limitu czasu zwiększa ilość czasu, przez jaki strona zdalna może przechowywać zasób lokalny przy życiu, taki jak pamięć, gniazda i wątki wykonujące synchroniczne operacje we/wy. Aplikacja powinna ocenić wartości domyślne i zachować ostrożność podczas zwiększania limitu czasu, ponieważ może otworzyć potencjalne wektory ataków, które mogą spowodować odmowę usługi z komputera zdalnego.

Niektóre inne opcje konfiguracji i zagadnienia dotyczące projektowania aplikacji, które należy dokładnie ocenić podczas korzystania z interfejsu API kanału WWSAPI:

  • Podczas korzystania z warstwy kanału/odbiornika, aplikacja jest odpowiedzialna za tworzenie i akceptowanie kanałów po stronie serwera. Podobnie aplikacja musi tworzyć i otwierać kanały po stronie klienta. Aplikacja powinna umieścić górną granicę dla tych operacji, ponieważ każdy kanał zużywa pamięć i inne ograniczone zasoby, takie jak gniazda. Aplikacja powinna być szczególnie ostrożna podczas tworzenia kanału w odpowiedzi na wszelkie działania wyzwalane przez zdalną stronę.
  • Do aplikacji należy napisanie logiki utworzenia i zaakceptowania kanałów. Każdy kanał zużywa ograniczone zasoby, takie jak pamięć i gniazda. Aplikacja powinna mieć górną granicę liczby kanałów, które chce zaakceptować, lub zdalna strona może nawiązać wiele połączeń, co prowadzi do OOM, a tym samym odmowy usługi. Powinna również aktywnie odbierać komunikaty z tych połączeń przy użyciu krótkiego limitu czasu. Jeśli żadne komunikaty nie zostaną odebrane, wówczas operacja przekroczy limit czasu i połączenie powinno zostać zwolnione.
  • To od aplikacji zależy, czy wyśle odpowiedź lub błąd, interpretując nagłówki ReplyTo lub FaultTo SOAP. Bezpieczną praktyką jest honorowanie tylko tych nagłówków ReplyTo lub FaultTo, które są "anonimowe", co oznacza, że istniejące połączenie (TCP, HTTP) lub adres IP źródła (UDP) powinny być używane do wysyłania odpowiedzi protokołu SOAP. Aplikacje powinny zachować szczególną ostrożność podczas tworzenia zasobów (takich jak kanał), aby odpowiedzieć na inny adres, chyba że wiadomość została podpisana przez stronę, która może mówić o adresie, do którego jest wysyłana odpowiedź.
  • Weryfikacja wykonywana w warstwie kanału nie zastępuje integralności danych osiągniętej za pośrednictwem zabezpieczeń. Aplikacja musi polegać na funkcjach zabezpieczeń interfejsu WWSAPI, aby upewnić się, że komunikuje się z zaufaną jednostką, a także musi polegać na zabezpieczeniach w celu zapewnienia integralności danych.

Podobnie istnieją opcje konfiguracji komunikatów i zagadnienia dotyczące projektowania aplikacji, które należy dokładnie ocenić podczas korzystania z interfejsu API komunikatów WWSAPI:

  • Rozmiar sterty używanej do przechowywania nagłówków wiadomości można skonfigurować przy użyciu właściwości WS_MESSAGE_PROPERTY_HEAP_PROPERTIES. Zwiększenie tej wartości pozwala na wykorzystanie większej ilości pamięci przez nagłówki komunikatu, co może prowadzić do problemu z brakiem pamięci (OOM).
  • Użytkownik obiektu komunikatu musi być świadomy, że interfejsy API dostępu do nagłówka mają złożoność O(n) w zależności od liczby nagłówków w komunikacie, ponieważ sprawdzają one obecność duplikatów. Projekty, które wymagają wielu nagłówków w komunikacie, mogą prowadzić do nadmiernego użycia procesora CPU.
  • Maksymalną liczbę nagłówków w komunikacie można skonfigurować przy użyciu właściwości WS_MESSAGE_PROPERTY_MAX_PROCESSED_HEADERS. Istnieje również niejawny limit na podstawie rozmiaru sterty wiadomości. Zwiększenie obu tych wartości pozwala na obecność większej liczby nagłówków, co wydłuża czas niezbędny do znalezienia nagłówka (w przypadku korzystania z interfejsów API dostępu do nagłówków).