Übersicht über Kanalebene

Die Kanalebene bietet eine Abstraktion des Transportkanals sowie nachrichten, die auf dem Kanal gesendet werden. Es enthält auch Funktionen für die Serialisierung von C-Datentypen in und aus SOAP-Strukturen. Die Kanalebene ermöglicht die vollständige Steuerung der Kommunikation durch Nachrichten , die aus gesendeten oder empfangenen Daten bestehen und Körper und Header enthalten, sowie Kanäle , die Nachrichtenaustauschprotokolle abstrahieren und Eigenschaften zum Anpassen von Einstellungen bereitstellen.

Nachricht

Eine Nachricht ist ein Objekt, das Netzwerkdaten kapselt, insbesondere Daten, die über ein Netzwerk übertragen oder empfangen werden. Die Nachrichtenstruktur wird durch SOAP definiert, mit einem separaten Satz von Headern und einem Nachrichtentext. Die Header werden in einem Speicherpuffer platziert, und der Nachrichtentext wird mithilfe einer Stream-API gelesen oder geschrieben.

Diagramm, das die Kopfzeile und den Text einer Nachricht zeigt.

Obwohl das Datenmodell einer Nachricht immer das XML-Datenmodell ist, ist das tatsächliche Drahtformat flexibel. Bevor eine Nachricht übertragen wird, wird sie mit einer bestimmten Codierung (z. B. Text, Binärdatei oder MTOM) codiert. Weitere Informationen zu Codierungen finden Sie unter WS_ENCODING .

Diagramm mit mehreren Nachrichtencodierungsformaten.

Kanal

Ein Kanal ist ein Objekt, das zum Senden und Empfangen von Nachrichten in einem Netzwerk zwischen zwei oder mehr Endpunkten verwendet wird.

Kanälen sind Daten zugeordnet, die beschreiben, wie die Nachricht beim Senden adressiert wird. Das Senden einer Nachricht in einem Kanal ist so, als ob sie in einer Rutsche platziert wird – der Kanal enthält die Informationen, an die die Nachricht gesendet werden soll und wie sie dorthin gelangen soll.

Diagramm mit Kanälen für Nachrichten.

Kanäle werden in Kanaltypen kategorisiert. Ein Kanaltyp gibt an, welche Richtungsmeldungen fließen können. Der Kanaltyp gibt auch an, ob der Kanal sitzungsbehaftet oder sitzungslos ist. Eine Sitzung wird als abstrakte Methode zum Korrelieren von Nachrichten zwischen zwei oder mehr Parteien definiert. Ein Beispiel für einen sitzungsbehafteten Kanal ist ein TCP-Kanal, der die TCP-Verbindung als konkrete Sitzungsimplementierung verwendet. Ein Beispiel für einen sitzungslosen Kanal ist UDP, der keinen zugrunde liegenden Sitzungsmechanismus aufweist. Obwohl HTTP über zugrunde liegende TCP-Verbindungen verfügt, wird diese Tatsache nicht direkt über diese API verfügbar gemacht, und daher wird HTTP auch als sitzungsloser Kanal betrachtet.

Diagramm, das sitzungsbehaftete und sitzungslose Kanaltypen zeigt.

Obwohl Kanaltypen die Richtungs- und Sitzungsinformationen für einen Kanal beschreiben, geben sie nicht an, wie der Kanal implementiert wird. Welches Protokoll sollte der Kanal verwenden? Wie schwer sollte der Kanal versuchen, die Nachricht zu übermitteln? Welche Art von Sicherheit wird verwendet? Ist es Singlecast oder Multicast? Diese Einstellungen werden als "Bindung" des Kanals bezeichnet. Die Bindung besteht aus folgendem:

Diagramm, das eine Liste der Kanaleigenschaften zeigt.

Listener

Um mit der Kommunikation zu beginnen, erstellt der Client ein Channel-Objekt. Aber wie erhält der Dienst sein Channel-Objekt? Dazu wird ein Listener erstellt. Zum Erstellen eines Listeners sind dieselben Bindungsinformationen erforderlich, die zum Erstellen eines Kanals erforderlich sind. Nachdem ein Listener erstellt wurde, kann die Anwendung Kanäle vom Listener akzeptieren. Da die Anwendung bei akzeptierenden Kanälen möglicherweise zurückfällt, führen Listener in der Regel eine Warteschlange mit Kanälen, die bereit sind zu akzeptieren (bis zu einem gewissen Kontingent).

Diagramm mit Kanälen in der Listener-Warteschlange.

Initiieren der Kommunikation (Client)

Verwenden Sie die folgende Sequenz, um die Kommunikation auf dem Client zu initiieren.

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

Akzeptieren der Kommunikation (Server)

Verwenden Sie die folgende Sequenz, um eingehende Kommunikationen auf dem Server zu akzeptieren.

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

Senden von Nachrichten (Client oder Server)

Verwenden Sie zum Senden von Nachrichten die folgende Sequenz.

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

Die WsSendMessage-Funktion lässt das Streaming nicht zu und geht davon aus, dass der Text nur ein Element enthält. Um diese Einschränkungen zu vermeiden, verwenden Sie die folgende Sequenz anstelle von 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

Die WsWriteBody-Funktion verwendet die Serialisierung, um die Textelemente zu schreiben. Verwenden Sie die folgende Sequenz anstelle von WsWriteBody, um die Daten direkt in den XML-Writer zu schreiben.

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?        

Die WsAddCustomHeader-Funktion verwendet die Serialisierung, um die Header auf den Headerpuffer der Nachricht festzulegen. Um den XML-Writer zum Schreiben eines Headers zu verwenden, verwenden Sie die folgende Sequenz anstelle von 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

Empfangen von Nachrichten (Client oder Server)

Verwenden Sie die folgende Sequenz, um Nachrichten zu empfangen.

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

Die WsReceiveMessage-Funktion lässt das Streaming nicht zu und geht davon aus, dass der Text nur ein Element enthält und dass der Typ der Nachricht (Aktion und Schema des Textkörpers) im Voraus bekannt ist. Um diese Einschränkungen zu vermeiden, verwenden Sie die folgende Sequenz anstelle von 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

Die WsReadBody-Funktion verwendet die Serialisierung, um die Textelemente zu lesen. Um die Daten direkt aus dem XML-Reader zu lesen, verwenden Sie die folgende Sequenz anstelle von 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

Die WsGetCustomHeader-Funktionen verwenden die Serialisierung, um die Header aus dem Headerpuffer der Nachricht abzurufen. Um den XML-Reader zum Lesen eines Headers zu verwenden, verwenden Sie die folgende Sequenz anstelle von 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
    }
}                

Anforderungsantwort (Client)

Die Ausführung einer Anforderungsantwort auf dem Client kann mit der folgenden Sequenz erfolgen.

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

Die WsRequestReply-Funktion setzt voraus, dass ein einzelnes Element für den Text der Anforderungs- und Antwortnachrichten vorhanden ist und dass der Typ der Nachricht (Aktion und Schema des Textkörpers) im Voraus bekannt ist. Um diese Einschränkungen zu vermeiden, können die Anforderungs- und Antwortnachrichten manuell gesendet werden, wie in der folgenden Sequenz gezeigt. Diese Sequenz entspricht der vorherigen Sequenz zum Senden und Empfangen einer Nachricht, sofern nicht angegeben.

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                

Anforderungsantwort (Server)

Verwenden Sie zum Empfangen einer Anforderungsnachricht auf dem Server dieselbe Sequenz, die im vorherigen Abschnitt zum Empfangen von Nachrichten beschrieben wurde.

Verwenden Sie die folgende Sequenz, um eine Antwort oder Eine Fehlermeldung zu senden.

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

Die WsSendReplyMessage-Funktion geht von einem einzelnen Element im Textkörper aus und lässt das Streaming nicht zu. Verwenden Sie die folgende Sequenz, um diese Einschränkungen zu vermeiden. Dies entspricht der früheren Sequenz für das Senden einer Nachricht, verwendet jedoch beim Initialisieren WS_REPLY_MESSAGE anstelle von WS_BLANK_MESSAGE .

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

Nachrichtenaustauschmuster

Die WS_CHANNEL_TYPE diktiert das für einen bestimmten Kanal mögliche Nachrichtenaustauschmuster. Der unterstützte Typ variiert je nach Bindung wie folgt:

Nachrichtenschleifen

Für jedes Nachrichtenaustauschmuster gibt es eine bestimmte "Schleife", die zum Senden oder Empfangen von Nachrichten verwendet werden kann. Die Schleife beschreibt die rechtliche Reihenfolge der Vorgänge, die zum Senden/Empfangen mehrerer Nachrichten erforderlich sind. Die Schleifen werden unten als Grammatikproduktionen beschrieben. Der Begriff "end" ist ein Empfang, bei dem WS_S_END zurückgegeben wird (siehe Rückgabewerte für Windows-Webdienste), der angibt, dass keine weiteren Nachrichten im Kanal verfügbar sind. Die parallele Produktion gibt an, dass für parallel(x & y) der Vorgang x gleichzeitig mit y ausgeführt werden kann.

Die folgenden Schleifen werden auf dem Client verwendet:

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

Die folgenden Schleifen werden auf dem Server verwendet:

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

Die Verwendung der WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING auf dem Server erfordert einen erfolgreichen Empfang, bevor das Senden auch mit einem Kanal vom Typ WS_CHANNEL_TYPE_DUPLEX_SESSION zulässig ist. Nach dem ersten Empfang. die reguläre Schleife gilt.

Beachten Sie, dass Kanäle vom Typ WS_CHANNEL_TYPE_REQUEST und WS_CHANNEL_TYPE_REPLY verwendet werden können, um unidirektionale Nachrichten zu senden und zu empfangen (sowie das Standardmuster für Anforderung/Antwort). Dies wird erreicht, indem der Antwortkanal geschlossen wird, ohne eine Antwort zu senden. In diesem Fall wird im Anforderungskanal keine Antwort empfangen. Der Rückgabewert WS_S_END Verwenden des WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING auf dem Server erfordert einen erfolgreichen Empfang, bevor das Senden auch mit einem Kanal vom Typ WS_CHANNEL_TYPE_DUPLEX_SESSION zulässig ist. Nach dem ersten Empfang wird die reguläre Schleife angewendet.

wird zurückgegeben, was angibt, dass keine Meldung verfügbar ist.

Client- oder Serverschleifen können parallel miteinander ausgeführt werden, indem mehrere Kanalinstanzen verwendet werden.

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

Nachrichtenfilterung

Ein Serverkanal kann empfangene Nachrichten filtern, die nicht für die Anwendung vorgesehen sind, z. B. Nachrichten, die einen Sicherheitskontext einrichten. In diesem Fall wird WS_S_END von WsReadMessageStart zurückgegeben, und in diesem Kanal sind keine Anwendungsmeldungen verfügbar. Dies signalisiert jedoch nicht, dass der Client beabsichtigte, die Kommunikation mit dem Server zu beenden. In einem anderen Kanal sind möglicherweise weitere Nachrichten verfügbar. Siehe WsShutdownSessionChannel.

Abbruch

Die WsAbortChannel-Funktion wird verwendet, um ausstehende E/A-Vorgänge für einen Kanal abzubrechen. Diese API wartet nicht, bis die E/A-Vorgänge abgeschlossen sind. Weitere Informationen finden Sie im WS_CHANNEL_STATE Zustandsdiagramm und in der Dokumentation zu WsAbortChannel .

Die WsAbortListener-API wird verwendet, um ausstehende E/A-Vorgänge für einen Listener abzubrechen. Diese API wartet nicht, bis die E/A-Vorgänge abgeschlossen sind. Das Abbrechen eines Listeners führt auch dazu, dass alle ausstehenden Annahmen abgebrochen werden. Weitere Informationen finden Sie unter WS_LISTENER_STATEZustandsdiagramm und WsAbortListener .

TCP

Die WS_TCP_CHANNEL_BINDING unterstützt SOAP über TCP. Die SOAP-über-TCP-Spezifikation baut auf dem .NET-Rahmenmechanismus auf.

Die Portfreigabe wird in dieser Version nicht unterstützt. Jeder geöffnete Listener muss eine andere Portnummer verwenden.

UDP

Die WS_UDP_CHANNEL_BINDING unterstützt SOAP über UDP.

Es gibt eine Reihe von Einschränkungen bei der UDP-Bindung:

  • Die Sicherheit wird nicht unterstützt.
  • Nachrichten können verloren oder dupliziert werden.
  • Es wird nur eine Codierung unterstützt: WS_ENCODING_XML_UTF8.
  • Nachrichten sind grundsätzlich auf 64.000 beschränkt und haben häufig eine größere Chance, verloren zu gehen, wenn die Größe die MTU des Netzwerks überschreitet.

HTTP

Die WS_HTTP_CHANNEL_BINDING unterstützt SOAP über HTTP.

Informationen zum Steuern von HTTP-spezifischen Headern auf dem Client und Server finden Sie unter WS_HTTP_MESSAGE_MAPPING.

Verwenden Sie zum Senden und Empfangen von Nicht-SOAP-Nachrichten auf dem Server WS_ENCODING_RAW für WS_CHANNEL_PROPERTY_ENCODING.

NAMEDPIPES

Die WS_NAMEDPIPE_CHANNEL_BINDING unterstützt SOAP über Named Pipes, wodurch die Kommunikation mit dem WCF-Dienst (Windows Communication Foundation) mithilfe von NetNamedPipeBinding ermöglicht wird.

Korrelieren von Anforderungs-/Antwortnachrichten

Anforderungs-/Antwortnachrichten werden auf zwei Arten korreliert:

  • Die Korrelation erfolgt mithilfe des Kanals als Korrelationsmechanismus. Wenn Sie z. B. WS_ADDRESSING_VERSION_TRANSPORT und WS_HTTP_CHANNEL_BINDING wird die Antwort für die Anforderungsnachricht durch die Tatsache korreliert, dass es sich um den Entitätstext der HTTP-Antwort handelt.
  • Die Korrelation erfolgt mithilfe der Header MessageID und RelatesTo. Dieser Mechanismus wird mit WS_ADDRESSING_VERSION_1_0 und WS_ADDRESSING_VERSION_0_9 (auch bei Verwendung von WS_HTTP_CHANNEL_BINDING) verwendet. In diesem Fall enthält die Anforderungsnachricht den MessageID-Header. Die Antwortnachricht enthält einen RelatesTo-Header mit dem Wert des MessageID-Headers der Anforderung. Der RelatesTo-Header ermöglicht es dem Client, eine Antwort mit einer gesendeten Anforderung zu korrelieren.

Die folgenden Kanalebenen-APIs verwenden automatisch die entsprechenden Korrelationsmechanismen basierend auf der WS_ADDRESSING_VERSION des Kanals.

Wenn diese APIs nicht verwendet werden, kann manuell auf die Header mit WsSetHeader oder WsGetHeader zugegriffen werden.

Benutzerdefinierte Kanäle und Listener

Wenn der vordefinierte Satz von Kanalbindungen nicht den Anforderungen der Anwendung entspricht, kann eine benutzerdefinierte Kanal- und Listenerimplementierung definiert werden, indem beim Erstellen des Kanals oder Listeners WS_CUSTOM_CHANNEL_BINDING angegeben wird. Die tatsächliche Implementierung des Kanals/Listeners wird als Eine Reihe von Rückrufen über WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS oderWS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS Eigenschaften angegeben. Nachdem ein benutzerdefinierter Kanal oder Listener erstellt wurde, ist das Ergebnis ein WS_CHANNEL - oder WS_LISTENER-Objekt , das mit vorhandenen APIs verwendet werden kann.

Ein benutzerdefinierter Kanal und Listener kann auch mit Dienstproxy und Diensthost verwendet werden, indem der wert für den WS_CUSTOM_CHANNEL_BINDING in der WS_CHANNEL_BINDING-Enumeration sowie die eigenschaften WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS und WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS beim Erstellen des Dienstproxys oder Diensthosts angegeben werden.

Sicherheit

Der Kanal ermöglicht das Einschränken der Menge an Arbeitsspeicher, die für verschiedene Aspekte von Vorgängen verwendet wird, durch Eigenschaften wie:

Diese Eigenschaften verfügen über Standardwerte, die für die meisten Szenarien konservativ und sicher sind. Standardwerte und etwaige Änderungen an ihnen sollten sorgfältig anhand potenzieller Angriffsvektoren bewertet werden, die einen Denial-of-Service durch einen Remotebenutzer verursachen können.

Der Kanal ermöglicht das Festlegen von Timeoutwerten für verschiedene Aspekte von Vorgängen über Eigenschaften wie:

Diese Eigenschaften verfügen über Standardwerte, die für die meisten Szenarien konservativ und sicher sind. Das Erhöhen der Timeoutwerte erhöht die Zeitspanne, in der eine Remotepartei eine lokale Ressource wie Arbeitsspeicher, Sockets und Threads mit synchronen E/A-Vorgängen speichern kann. Eine Anwendung sollte die Standardwerte auswerten und beim Erhöhen eines Timeouts vorsichtshalber vorgehen, da dies potenzielle Angriffsvektoren eröffnen kann, die zu Denial-of-Service von einem Remotecomputer führen können.

Einige der anderen Konfigurationsoptionen und Anwendungsentwurfsüberlegungen, die bei Verwendung der WWSAPI-Kanal-API sorgfältig ausgewertet werden sollten:

  • Bei Verwendung der Kanal-/Listenerebene liegt es an der Anwendung, Kanäle auf serverseitiger Seite zu erstellen und zu akzeptieren. Ebenso liegt es an der Anwendung, Kanäle auf clientseitiger Seite zu erstellen und zu öffnen. Eine Anwendung sollte für diese Vorgänge eine Obergrenze festlegen, da jeder Kanal Arbeitsspeicher und andere eingeschränkte Ressourcen wie Sockets verbraucht. Eine Anwendung sollte besonders vorsichtig sein, wenn sie einen Kanal als Reaktion auf aktionen erstellt, die von einer Remotepartei ausgelöst werden.
  • Es liegt an der Anwendung, die Logik zu schreiben, um Kanäle zu erstellen und diese zu akzeptieren. Jeder Kanal verbraucht begrenzte Ressourcen wie Arbeitsspeicher und Sockets. Eine Anwendung sollte über eine Obergrenze für die Anzahl der Kanäle verfügen, die sie akzeptieren möchte, oder eine Remotepartei könnte viele Verbindungen herstellen, was zu OOM und somit zu Denial-of-Service führt. Es sollte auch aktiv Nachrichten von diesen Verbindungen mit einem kleinen Timeout empfangen. Wenn keine Nachrichten empfangen werden, tritt für den Vorgang ein Timeout auf, und die Verbindung sollte aufgehoben werden.
  • Es liegt an einer Anwendung, eine Antwort oder einen Fehler zu senden, indem die SOAP-Header ReplyTo oder FaultTo interpretiert werden. Die sichere Methode besteht darin, nur einen ReplyTo- oder FaultTo-Header zu berücksichtigen, der "anonym" ist, was bedeutet, dass die vorhandene Verbindung (TCP, HTTP) oder die Quell-IP (UDP) zum Senden der SOAP-Antwort verwendet werden sollte. Anwendungen sollten beim Erstellen von Ressourcen (z. B. einem Kanal) äußerst vorsichtig sein, um an eine andere Adresse zu antworten, es sei denn, die Nachricht wurde von einer Partei signiert, die für die Adresse sprechen kann, an die die Antwort gesendet wird.
  • Die überprüfung auf der Kanalebene ist kein Ersatz für die Datenintegrität, die durch Sicherheit erreicht wird. Eine Anwendung muss sich auf Sicherheitsfeatures der WWSAPI verlassen, um sicherzustellen, dass sie mit einer vertrauenswürdigen Entität kommuniziert, und muss sich auch auf die Sicherheit verlassen, um die Datenintegrität sicherzustellen.

Ebenso gibt es Optionen für die Nachrichtenkonfiguration und Überlegungen zum Anwendungsentwurf, die bei Verwendung der WWSAPI-Nachrichten-API sorgfältig ausgewertet werden sollten:

  • Die Größe des Heaps, der zum Speichern der Header einer Nachricht verwendet wird, kann mithilfe der eigenschaft WS_MESSAGE_PROPERTY_HEAP_PROPERTIES konfiguriert werden. Wenn Sie diesen Wert erhöhen, kann mehr Arbeitsspeicher von den Headern der Nachricht beansprucht werden, was zu OOM führen kann.
  • Der Benutzer des Nachrichtenobjekts muss erkennen, dass die Headerzugriffs-APIs in Bezug auf die Anzahl der Header in der Nachricht O(n) sind, da er auf Duplikate überprüft. Designs, die viele Header in einer Nachricht erfordern, können zu einer übermäßigen CPU-Auslastung führen.
  • Die maximale Anzahl von Headern in einer Nachricht kann mithilfe der eigenschaft WS_MESSAGE_PROPERTY_MAX_PROCESSED_HEADERS konfiguriert werden. Es gibt auch eine implizite Beschränkung basierend auf der Größe des Heaps der Nachricht. Wenn Sie beide Werte erhöhen, können mehr Header vorhanden sein. Dies erhöht die Zeit, die zum Suchen eines Headers erforderlich ist (bei Verwendung der Headerzugriffs-APIs).