Übersicht über die Kanalebene
Die Kanalebene bietet eine Abstraktion des Transportkanals sowie von Nachrichten, die auf dem Kanal gesendet werden. Sie enthält auch Funktionen für die Serialisierung von C-Datentypen in und aus SOAP-Strukturen. Die Kanalebene ermöglicht die vollständige Kontrolle über die Kommunikation mit Nachrichten, die aus gesendeten oder empfangenen Daten bestehen und Text und Header enthalten, und Kanälen, die Nachrichtenaustauschprotokolle abstrahieren und Eigenschaften zum Anpassen von Einstellungen bereitstellen.
Message
Eine Nachricht ist ein Objekt, das Netzwerkdaten kapselt, insbesondere Daten, die über ein Netzwerk übertragen oder empfangen werden. Die Nachrichtenstruktur wird von SOAP mit einem diskreten Satz von Headern und einem Nachrichtentext definiert. Die Header werden in einem Speicherpuffer platziert, und der Nachrichtentext wird mithilfe einer Stream-API gelesen oder geschrieben.

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

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 auf einem Kanal ist wie das Platzieren in einer N-Mail. Der Kanal enthält die Informationen, wohin die Nachricht gesendet werden soll und wie sie dort empfangen werden soll.

Kanäle werden in Kanaltypen kategorisiert. Ein Kanaltyp gibt an, in welche Richtung Nachrichten fließen können. Der Kanaltyp gibt auch an, ob der Kanal sitzungs- oder sitzungslos ist. Eine Sitzung ist als abstrakte Methode zum Korrelieren von Nachrichten zwischen zwei oder mehr Parteien definiert. Ein Beispiel für einen sitzungsvollen 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 hat. Obwohl HTTP über zugrunde liegende TCP-Verbindungen verfügt, wird diese Tatsache nicht direkt über diese API verfügbar gemacht und daher auch als sitzungsloser Kanal betrachtet.

Obwohl Kanaltypen die Richtung und Sitzungsinformationen für einen Kanal beschreiben, geben sie nicht an, wie der Kanal implementiert wird. Welches Protokoll sollte der Kanal verwenden? Wie schwierig sollte der Kanal versuchen, die Nachricht zu senden? Welche Art von Sicherheit wird verwendet? Ist es Singlecast oder Multicast? Diese Einstellungen werden als "Bindung" des Kanals bezeichnet. Die Bindung besteht aus folgendem Code:
- Eine _ WS-KANALBINDUNG, _die das zu verwendende Übertragungsprotokoll identifiziert (TCP, UDP, HTTP, NAMEDPIPE).
- Eine _ WS-SICHERHEITSBESCHREIBUNG, _die angibt, wie der Kanal geschützt wird.
- Ein satz von WS _ CHANNEL _ PROPERTYs, die zusätzliche optionale Einstellungen angeben. Die Liste der Eigenschaften finden Sie unter WS CHANNEL PROPERTY ID (WS-CHANNEL-EIGENSCHAFTEN-ID). _ _ _

Listener
Um mit der Kommunikation zu beginnen, erstellt der Client ein Channel-Objekt. Aber wie bekommt 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 der Annahme von Kanälen möglicherweise im Rückstand ist, behalten Listener in der Regel eine Warteschlange von Kanälen bei, die akzeptiert werden können (bis zu einem bestimmten Kontingent).

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)
Um eingehende Kommunikation auf dem Server zu akzeptieren, verwenden Sie die folgende Sequenz.
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 die folgende Sequenz, um Nachrichten zu senden.
WsCreateMessageForChannel
for each message being sent
{
WsSendMessage // send message
WsResetMessage? // reset if sending another message
}
WsFreeMessage
Die WsSendMessage-Funktion lässt kein Streaming zu und geht davon aus, dass der Text nur ein Element enthält. Verwenden Sie anstelle von WsSendMessage die folgende Sequenz, um diese Einschränkungen zu vermeiden.
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. Um die Daten direkt in den XML Writer zu schreiben, verwenden Sie die folgende Sequenz anstelle von 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?
Die WsAddCustomHeader-Funktion verwendet die Serialisierung, um die Header auf den Headerpuffer der Nachricht zu setzen. Verwenden Sie die folgende Sequenz anstelle von WsAddCustomHeader, um den XML Writer zum Schreiben eines Headers zu verwenden.
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 kein Streaming 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 zu erhalten. Verwenden Sie die folgende Sequenz anstelle von WsGetCustomHeader, um den XML-Reader zum Lesen eines Headers zu verwenden.
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)
Das Ausführen einer Anforderung-Antwort-Anforderung 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 geht von einem einzelnen Element für den Text der Anforderungs- und Antwortnachrichten aus, 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 Antwortnachricht manuell gesendet werden, wie in der folgenden Sequenz gezeigt. Diese Sequenz entspricht der früheren Sequenz zum Senden und Empfangen einer Nachricht, sofern nicht anders 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)
Um eine Anforderungsnachricht auf dem Server zu empfangen, verwenden Sie dieselbe Sequenz wie im vorherigen Abschnitt zum Empfangen von Nachrichten beschrieben.
Verwenden Sie die folgende Sequenz, um eine Antwort- oder 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 Text aus und lässt kein Streaming zu. Um diese Einschränkungen zu vermeiden, verwenden Sie die folgende Sequenz. Dies ist identisch mit der früheren Sequenz zum Senden einer Nachricht, verwendet bei der Initialisierung jedoch 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
Der _ WS-KANALTYP _ bestimmt das für einen bestimmten Kanal mögliche Nachrichtenaustauschmuster. Der unterstützte Typ variiert je nach Bindung wie folgt:
- WS _ HTTP _ CHANNEL _ BINDING unterstützt WS CHANNEL TYPE _ _ _ REQUEST auf dem Client und WS CHANNEL TYPE _ _ _ REPLY auf dem Server.
- WS _ TCP _ CHANNEL _ BINDING unterstützt WS CHANNEL TYPE DUPLEX _ _ _ _ SESSION auf dem Client und WS CHANNEL TYPE DUPLEX _ _ _ _ SESSION auf dem Server.
- WS _ UDP _ CHANNEL _ BINDING unterstützt WS CHANNEL TYPE _ _ _ DUPLEX auf dem Client und WS CHANNEL TYPE _ _ _ INPUT auf dem Server.
- WS _ NAMEDPIPE _ CHANNEL _ BINDING unterstützt WS CHANNEL TYPE _ _ _ DUPLEX auf dem Client und WS CHANNEL TYPE _ _ _ INPUT auf dem Server.
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 Endbegriff ist ein Empfang, bei dem WS _ S _ END zurückgegeben wird (siehe Windows Webdienste-Rückgabewerte), der angibt, dass im Kanal keine nachrichten mehr 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 angewendet wird.
Beachten Sie, dass Kanäle vom Typ WS _ CHANNEL TYPE _ _ REQUEST und WS CHANNEL TYPE _ _ _ REPLY zum Senden und Empfangen von einfachen Nachrichten (sowie zum Standardmuster für Anforderung/Antwort) verwendet werden können. 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 Mithilfe der WS _ SECURITY CONTEXT MESSAGE _ SECURITY _ _ _ BINDING auf dem Server ist ein erfolgreicher Empfang erforderlich, 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 zueinander 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 auf diesem Kanal sind keine Anwendungsmeldungen verfügbar. Dies signalisiert jedoch nicht, dass der Client die Kommunikation mit dem Server beenden wollte. Möglicherweise sind auf einem anderen Kanal weitere Nachrichten verfügbar. Weitere Informationen finden Sie unter WsShutdownSessionChannel.
Abbruch
Die WsAbortChannel-Funktion wird verwendet, um ausstehende E/A für einen Kanal abzubruchen. Diese API wartet nicht auf den Abschluss der E/A-Operation(en). Weitere Informationen finden Sie im WS _ CHANNEL _ STATE-Statusdiagramm und in der Dokumentation zu WsAbortChannel.
Die WsAbortListener-API wird verwendet, um ausstehende E/A für einen Listener abzubruchen. Diese API wartet nicht auf den Abschluss der E/A-Operation(en). Das Abbrechen eines Listeners verursacht auch, dass alle ausstehenden Annahmen abgebrochen werden. Weitere Informationen finden Sie im WS LISTENER _ _ STATE-Statusdiagramm und im WsAbortListener.
TCP
Die _ WS-TCP-KANALBINDUNG _ _ unterstützt SOAP über TCP. Die SOAP over 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-KANALBINDUNG _ _ 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 gehen 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 höhere Wahrscheinlichkeit, dass sie verloren gehen, wenn die Größe die MTU des Netzwerks überschreitet.
HTTP
Die _ WS-HTTP-KANALBINDUNG _ _ unterstützt SOAP über HTTP.
Informationen zum Steuern von HTTP-spezifischen Headern auf dem Client und Server finden Sie unter WS _ HTTP MESSAGE _ _ MAPPING.
Um Nicht-SOAP-Nachrichten auf dem Server zu senden und zu empfangen, verwenden Sie WS _ ENCODING _ RAW für WS _ CHANNEL PROPERTY _ _ ENCODING.
NAMEDPIPES
Die WS _ NAMEDPIPE _ CHANNEL _ BINDING unterstützt SOAP über Named Pipes und ermöglicht die Kommunikation mit dem wcf-Dienst (Windows Communication Foundation) mithilfe von NetNamedPipeBinding.
Korrelieren von Anforderungs-/Antwortnachrichten
Anforderungs-/Antwortnachrichten werden auf zwei Arten korreliert:
- Die Korrelation erfolgt mithilfe des Kanals als Korrelationsmechanismus. Wenn Sie beispielsweise WS _ ADDRESSING VERSION _ _ TRANSPORT und WS HTTP CHANNEL _ _ _ BINDING verwenden, wird die Antwort für die Anforderungsnachricht mit der Anforderung korreliert, da 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 verwendet (auch bei Verwendung von WS HTTP CHANNEL _ _ _ BINDING). In diesem Fall enthält die Anforderungsnachricht den MessageID-Header. Die Antwortnachricht enthält einen RelatesTo-Header, der über den Wert des MessageID-Headers der Anforderung verfügt. Mit dem RelatesTo-Header kann der Client eine Antwort mit einer gesendeten Anforderung korrelieren.
Die folgenden Kanalebenen-APIs verwenden automatisch die entsprechenden Korrelationsmechanismen, die auf der _ WS-ADRESSIERUNGSVERSION _ des Kanals basieren.
Wenn diese APIs nicht verwendet werden, können die Header manuell hinzugefügt und mit WsSetHeader oder WsGetHeader aufgerufen werden.
Benutzerdefinierte Kanäle und Listener
Wenn der vordefinierte Satz von Kanalbindungen die Anforderungen der Anwendung nicht erfüllt, können ein benutzerdefinierter Kanal und eine Listenerimplementierung definiert werden, indem WS _ CUSTOM CHANNEL _ _ BINDING beim Erstellen des Kanals oder Listeners angegeben wird. Die tatsächliche Implementierung des Kanals bzw. Listeners wird als Satz von Rückrufen über die EIGENSCHAFTEN BENUTZERDEFINIERTER WS-KANALEIGENSCHAFTENRÜCKRUFE oder BENUTZERDEFINIERTE LISTENER _ _ _ _ _ CALLBACKS-Eigenschaften des WS-LISTENERS angegeben. _ _ _ _ _ Sobald ein benutzerdefinierter Kanal oder Listener erstellt wurde, ist das Ergebnis ein _ WS-KANAL- oder WS _ LISTENER-Objekt, das mit vorhandenen APIs verwendet werden kann.
Ein benutzerdefinierter Kanal und Listener kann auch mit dem Dienstproxy und dem Diensthost verwendet werden, indem der WS _ CUSTOM _ CHANNEL _ BINDING-Wert in der WS-KANALBINDUNGsenumeration _ _ und die EIGENSCHAFTEN BENUTZERDEFINIERTER WS-KANALEIGENSCHAFT _ _ _ _ _ CALLBACKS und WS LISTENER PROPERTY CUSTOM LISTENER _ _ _ _ _ CALLBACKS beim Erstellen des Dienstproxys oder Diensthosts angegeben werden.
Sicherheit
Der Kanal ermöglicht das Beschränken der Arbeitsspeichermenge, die für verschiedene Aspekte von Vorgängen verwendet wird, durch Eigenschaften wie die folgenden:
- WS _ _ _ CHANNEL-EIGENSCHAFT _ MAX. _ GEPUFFERTE _ NACHRICHTENGRÖßE,
- WS _ _ _ CHANNEL-EIGENSCHAFT _ MAX. GRÖßE DER _ _ GESTREAMTEN NACHRICHT,
- WS _ _ _ CHANNEL-EIGENSCHAFT _ MAX. _ GESTREAMTE _ STARTGRÖßE,
- WS _ _CHANNEL-EIGENSCHAFT _ _ MAX. _ _ HTTP-ANFORDERUNGSHEADER _ _ PUFFERGRÖßE,
- WS _ DIE MAXIMALE _ _ _ SITZUNGSWÖRTERBUCHGRÖßE _ DER _ KANALEIGENSCHAFT.
Diese Eigenschaften verfügen über Standardwerte, die für die meisten Szenarien konservativ und sicher sind. Standardwerte und alle Änderungen an ihnen sollten sorgfältig anhand potenzieller Angriffsvektoren ausgewertet werden, die einen Denial-of-Service-Angriff durch einen Remotebenutzer verursachen können.
Der Kanal ermöglicht das Festlegen von Timeoutwerten für verschiedene Aspekte von Vorgängen über Eigenschaften wie:
- 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 _ TIMEOUT _ FÜR DAS SCHLIEßEN DER _ _ KANALEIGENSCHAFT.
Diese Eigenschaften verfügen über Standardwerte, die für die meisten Szenarien konservativ und sicher sind. Das Erhöhen von Timeoutwerten erhöht die Zeit, die eine Remote-Partei eine lokale Ressource wie Arbeitsspeicher, Sockets und Threads, die synchrone E/A-Daten ausführen, zunehmen kann. Eine Anwendung sollte die Standardwerte auswerten und beim Erhöhen eines Timeouts Vorsicht walten lassen, da sie potenzielle Angriffsvektoren öffnen kann, die zu Denial-of-Service-Angriffen von einem Remotecomputer führen können.
Einige der anderen Konfigurationsoptionen und Überlegungen zum Anwendungsentwurf, die bei verwendung der WWSAPI-Kanal-API sorgfältig ausgewertet werden sollten:
- Wenn Sie die Kanal-/Listenerebene verwenden, liegt es in der Verantwortung 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 setzen, da jeder Kanal Arbeitsspeicher und andere eingeschränkte Ressourcen wie Sockets verbraucht. Eine Anwendung sollte besonders vorsichtig sein, wenn sie als Reaktion auf aktionen, die von einer Remote-Partei ausgelöst werden, einen Kanal erstellt.
- Die Anwendung muss die Logik schreiben, um Kanäle zu erstellen und zu akzeptieren. Jeder Kanal verbraucht eingeschränkte Ressourcen wie Arbeitsspeicher und Sockets. Eine Anwendung sollte eine Obergrenze für die Anzahl der Kanäle haben, die sie akzeptieren möchte, oder eine Remoteseite könnte viele Verbindungen herstellen, was zu OOM und somit zu Denial-of-Service-Angriffen führt. Sie sollte auch aktiv Nachrichten von diesen Verbindungen mit einem kleinen Timeout empfangen. Wenn keine Nachrichten empfangen werden, kommt es beim Vorgang zu einem Time out, und die Verbindung sollte freigegeben werden.
- Es liegt in der Hand einer Anwendung, eine Antwort oder einen Fehler zu senden, indem die ReplyTo- oder FaultTo-SOAP-Header interpretiert werden. Die sichere Vorgehensweise besteht in der ausschließlichen Honorierung eines ReplyTo- oder FaultTo-Headers, der "anonym" ist. Dies bedeutet, dass die vorhandene Verbindung (TCP, HTTP) oder 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, die auf der Kanalebene durchgeführt wird, 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 sie muss sich auch auf sicherheit verlassen, um die Datenintegrität sicherzustellen.
Ebenso gibt es Nachrichtenkonfigurationsoptionen und Überlegungen zum Anwendungsentwurf, die bei der 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 WS _ MESSAGE PROPERTY _ _ HEAP _ PROPERTIES-Eigenschaft konfiguriert werden. Durch Erhöhen dieses Werts kann mehr Arbeitsspeicher von den Headern der Nachricht verbraucht 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 sie nach Duplikaten suchen. Entwürfe, 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 WS _ MESSAGE PROPERTY MAX PROCESSED _ _ _ _ HEADERS-Eigenschaft konfiguriert werden. Es gibt auch einen impliziten Grenzwert, der auf der Größe des Heaps der Nachricht basiert. Wenn Sie beide Werte erhöhen, können mehr Header vorhanden sein, was die Zeit für die Suche nach einem Header (bei Verwendung der Headerzugriffs-APIs) verfing.