채널 계층 개요

채널 계층은 채널에서 전송된 메시지뿐만 아니라 전송 채널의 추상화도 제공합니다. 또한 SOAP 구조에 대한 C 데이터 형식의 직렬화를 위한 함수도 포함됩니다. 채널 계층을 사용하면 전송되거나 수신된 데이터와 본문 및 헤더가 포함된 메시지 와 메시지 교환 프로토콜을 추상화하고 설정을 사용자 지정하기 위한 속성을 제공하는 채널 로 구성된 메시지를 통해 통신을 완전히 제어할 수 있습니다.

메시지

메시지는 네트워크 데이터, 특히 네트워크를 통해 전송되거나 수신되는 데이터를 캡슐화하는 개체입니다. 메시지 구조는 SOAP로 정의되며, 개별 헤더 집합과 메시지 본문이 있습니다. 헤더는 메모리 버퍼에 배치되고 메시지 본문은 스트림 API를 사용하여 읽거나 씁니다.

Diagram showing the header and body of a message.

메시지의 데이터 모델은 항상 XML 데이터 모델이지만 실제 유선 형식은 유연합니다. 메시지가 전송되기 전에 특정 인코딩(예: 텍스트, 이진 또는 MTOM)을 사용하여 인코딩됩니다. 인코딩에 대한 자세한 내용은 WS_ENCODING 참조하세요.

Diagram showing several message encoding formats.

채널

채널은 두 개 이상의 엔드포인트 간에 네트워크에서 메시지를 보내고 받는 데 사용되는 개체입니다.

채널에는 메시지를 보낼 때 메시지를 처리하는 방법을 설명하는 관련 데이터가 있습니다. 채널에 메시지를 보내는 것은 메시지를 슈트에 넣는 것과 같습니다. 채널에는 메시지가 어디로 가야 하는지, 그리고 메시지를 가져오는 방법이 포함됩니다.

Diagram showing channels for messages.

채널은 채널 유형으로 분류됩니다. 채널 유형은 메시지가 흐를 수 있는 방향을 지정합니다. 또한 채널 유형은 채널이 세션 또는 세션 없는지 여부를 식별합니다. 세션은 둘 이상의 당사자 간에 메시지를 상호 연결하는 추상적인 방법으로 정의됩니다. 세션 채널의 예로 TCP 채널을 예로 들어 TCP 연결을 구체적인 세션 구현으로 사용합니다. 세션 없는 채널의 예로는 기본 세션 메커니즘이 없는 UDP가 있습니다. HTTP에는 기본 TCP 연결이 있지만 이 사실은 이 API를 통해 직접 노출되지 않으므로 HTTP도 세션 없는 채널로 간주됩니다.

Diagram showing sessionful and sessionless channel types.

채널 형식은 채널의 방향 및 세션 정보를 설명하지만 채널 구현 방법을 지정하지는 않습니다. 채널에서 어떤 프로토콜을 사용해야 하나요? 채널이 메시지를 배달하는 데 얼마나 열심히 노력해야 하나요? 어떤 종류의 보안이 사용됩니까? 싱글캐스트인가요, 멀티캐스트인가요? 이러한 설정을 채널의 "바인딩"이라고 합니다. 바인딩은 다음으로 구성됩니다.

Diagram showing a list of channel properties.

수신기

통신을 시작하기 위해 클라이언트는 Channel 개체를 만듭니다. 그러나 서비스는 Channel 개체를 어떻게 얻을 수 있을까요? 수신기를 만들어 이 작업을 수행 합니다. 수신기를 만들려면 채널을 만드는 데 필요한 것과 동일한 바인딩 정보가 필요합니다. 수신기가 만들어지면 애플리케이션은 수신기에서 채널을 수락할 수 있습니다. 애플리케이션이 채널을 수락하는 데 뒤처질 수 있으므로 수신기는 일반적으로 허용할 준비가 된 채널 큐를 유지합니다(최대 일부 할당량).

Diagram showing channels in the Listener queue.

통신 시작(클라이언트)

클라이언트에서 통신을 시작하려면 다음 시퀀스를 사용합니다.

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

통신 수락(서버)

서버에서 들어오는 통신을 허용하려면 다음 시퀀스를 사용합니다.

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

메시지 보내기(클라이언트 또는 서버)

메시지를 보내려면 다음 시퀀스를 사용합니다.

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

WsSendMessage 함수는 스트리밍을 허용하지 않으며 본문에 하나의 요소만 포함되어 있다고 가정합니다. 이러한 제약 조건을 방지하려면 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

WsWriteBody 함수는 serialization을 사용하여 본문 요소를 작성합니다. XML 기록기에 직접 데이터를 쓰려면 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?        

WsAddCustomHeader 함수는 serialization을 사용하여 헤더를 메시지의 헤더 버퍼로 설정합니다. XML 기록기를 사용하여 헤더를 작성하려면 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

메시지 수신(클라이언트 또는 서버)

메시지를 받으려면 다음 시퀀스를 사용합니다.

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

WsReceiveMessage 함수는 스트리밍을 허용하지 않으며 본문에 하나의 요소만 포함되어 있고 메시지 형식(본문의 동작 및 스키마)이 미리 알려져 있다고 가정합니다. 이러한 제약 조건을 방지하려면 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

WsReadBody 함수는 serialization을 사용하여 본문 요소를 읽습니다. XML 판독기에서 직접 데이터를 읽으려면 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

WsGetCustomHeader 함수는 serialization을 사용하여 메시지의 헤더 버퍼에서 헤더를 가져옵니다. XML 판독기를 사용하여 헤더를 읽으려면 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
    }
}                

회신 요청(클라이언트)

클라이언트에서 요청-회신을 수행하는 작업은 다음 순서로 수행할 수 있습니다.

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

WsRequestReply 함수는 요청 및 회신 메시지의 본문에 대한 단일 요소를 가정하고 메시지 형식(본문의 동작 및 스키마)을 미리 알고 있다고 가정합니다. 이러한 제한을 방지하기 위해 다음 시퀀스와 같이 요청 및 회신 메시지를 수동으로 보낼 수 있습니다. 이 시퀀스는 기록된 경우를 제외하고 메시지를 보내고 받기 위한 이전 시퀀스와 일치합니다.

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                

회신 요청(서버)

서버에서 요청 메시지를 받으려면 메시지 수신에 대해 이전 섹션에 설명된 것과 동일한 순서를 사용합니다.

회신 또는 오류 메시지를 보내려면 다음 시퀀스를 사용합니다.

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

WsSendReplyMessage 함수는 본문의 단일 요소를 가정하며 스트리밍을 허용하지 않습니다. 이러한 제한을 방지하려면 다음 시퀀스를 사용합니다. 이는 메시지를 보내는 이전 시퀀스와 동일하지만 초기화할 때 WS_BLANK_MESSAGE 대신 WS_REPLY_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

메시지 교환 패턴

WS_CHANNEL_TYPE 지정된 채널에 대해 가능한 메시지 교환 패턴을 나타냅니다. 지원되는 형식은 다음과 같이 바인딩에 따라 달라집니다.

메시지 루프

각 메시지 교환 패턴에는 메시지를 보내거나 받는 데 사용할 수 있는 특정 "루프"가 있습니다. 루프는 여러 메시지를 보내거나 받는 데 필요한 작업의 법적 순서를 설명합니다. 루프는 아래에 문법 프로덕션으로 설명되어 있습니다. 'end' 용어는 채널에서 사용할 수 있는 메시지가 더 이상 없음을 나타내는 WS_S_END 반환되는 수신(Windows Web Services 반환 값 참조)입니다. 병렬 프로덕션은 병렬(x & y)의 경우 x 연산이 y와 동시에 수행될 수 있음을 지정합니다.

클라이언트에서 사용되는 루프는 다음과 같습니다.

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

서버에서 사용되는 루프는 다음과 같습니다.

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

서버에서 WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING 사용하려면 WS_CHANNEL_TYPE_DUPLEX_SESSION 형식의 채널에서도 보내기가 허용되기 전에 성공적인 수신이 필요합니다. 첫 번째 수신 후입니다. 일반 루프가 적용됩니다.

WS_CHANNEL_TYPE_REQUESTWS_CHANNEL_TYPE_REPLY 형식의 채널은 단방향 메시지(표준 요청-회신 패턴)를 보내고 받는 데 사용할 수 있습니다. 이 작업은 회신을 보내지 않고 회신 채널을 닫아 수행됩니다. 이 경우 요청 채널에 회신이 수신되지 않습니다. 반환 값 WS_S_END 서버에서 WS_SECURITY_CONTEXT_MESSAGE_SECURITY_BINDING 사용하려면 WS_CHANNEL_TYPE_DUPLEX_SESSION 형식의 채널에서도 보내기 전에 성공적인 수신이 필요합니다. 첫 번째 수신 후 일반 루프가 적용됩니다.

가 반환되며, 이는 사용할 수 있는 메시지가 없음을 나타냅니다.

클라이언트 또는 서버 루프는 여러 채널 인스턴스를 사용하여 서로 병렬로 수행할 수 있습니다.

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

메시지 필터링

서버 채널은 보안 컨텍스트를 설정하는 메시지와 같이 애플리케이션용이 아닌 수신된 메시지를 필터링할 수 있습니다. 이 경우 WS_S_ENDWsReadMessageStart 에서 반환되며 해당 채널에서 애플리케이션 메시지를 사용할 수 없습니다. 그러나 클라이언트가 서버와의 통신을 종료하려고 했다는 신호는 아닙니다. 다른 채널에서 더 많은 메시지를 사용할 수 있습니다. WsShutdownSessionChannel을 참조하세요.

취소

WsAbortChannel 함수는 채널에 대해 보류 중인 IO를 취소하는 데 사용됩니다. 이 API는 IO 작업이 완료될 때까지 기다리지 않습니다. 자세한 내용은 WsAbortChannel에 대한 WS_CHANNEL_STATE 상태 다이어그램 및 설명서를 참조하세요.

WsAbortListener API는 수신기에 대해 보류 중인 IO를 취소하는 데 사용됩니다. 이 API는 IO 작업이 완료될 때까지 기다리지 않습니다. 수신기를 중단하면 보류 중인 모든 수락도 중단됩니다. 자세한 내용은 WS_LISTENER_STATE 상태 다이어그램 및 WsAbortListener 를 참조하세요.

TCP

WS_TCP_CHANNEL_BINDING TCP를 통해 SOAP를 지원합니다. SOAP over TCP 사양은 .NET 프레이밍 메커니즘을 기반으로 합니다.

포트 공유는 이 버전에서 지원되지 않습니다. 열려 있는 각 수신기는 다른 포트 번호를 사용해야 합니다.

UDP

WS_UDP_CHANNEL_BINDING UDP를 통해 SOAP를 지원합니다.

UDP 바인딩에는 여러 가지 제한 사항이 있습니다.

  • 보안에 대한 지원은 없습니다.
  • 메시지가 손실되거나 중복될 수 있습니다.
  • WS_ENCODING_XML_UTF8 인코딩은 하나만 지원됩니다.
  • 메시지는 기본적으로 64k로 제한되며, 크기가 네트워크의 MTU를 초과하면 손실될 가능성이 더 큰 경우가 자주 있습니다.

HTTP

WS_HTTP_CHANNEL_BINDING HTTP를 통한 SOAP를 지원합니다.

클라이언트 및 서버에서 HTTP 특정 헤더를 제어하려면 WS_HTTP_MESSAGE_MAPPING 참조하세요.

서버에서 SOAP가 아닌 메시지를 보내고 받으려면 WS_CHANNEL_PROPERTY_ENCODING WS_ENCODING_RAW 사용합니다.

NAMEDPIPES

WS_NAMEDPIPE_CHANNEL_BINDING 명명된 파이프에 대한 SOAP를 지원하므로 NetNamedPipeBinding을 사용하여 Windows Communication Foundation(WCF) 서비스와 통신할 수 있습니다.

요청/회신 메시지 상관 관계 지정

요청/회신 메시지는 다음 두 가지 방법 중 하나로 상호 연관됩니다.

  • 상관 관계는 채널을 상관 관계 메커니즘으로 사용하여 수행됩니다. 예를 들어 WS_ADDRESSING_VERSION_TRANSPORT 사용하고 WS_HTTP_CHANNEL_BINDING 경우 요청 메시지에 대한 회신은 HTTP 응답의 엔터티 본문이라는 사실에 의해 요청과 상관 관계가 있습니다.
  • 상관 관계는 MessageID 및 RelatesTo 헤더를 사용하여 수행됩니다. 이 메커니즘은 WS_HTTP_CHANNEL_BINDING 사용하는 경우에도 WS_ADDRESSING_VERSION_1_0WS_ADDRESSING_VERSION_0_9 사용됩니다. 이 경우 요청 메시지에 MessageID 헤더가 포함됩니다. 응답 메시지에는 요청의 MessageID 헤더 값이 있는 RelatesTo 헤더가 포함됩니다. RelatesTo 헤더를 사용하면 클라이언트가 보낸 요청과 응답을 상호 연결할 수 있습니다.

다음 채널 계층 API는 채널의 WS_ADDRESSING_VERSION 따라 적절한 상관 관계 메커니즘을 자동으로 사용합니다.

이러한 API를 사용하지 않는 경우 WsSetHeader 또는 WsGetHeader를 사용하여 헤더를 수동으로 추가하고 액세스할 수 있습니다.

사용자 지정 채널 및 수신기

미리 정의된 채널 바인딩 집합이 애플리케이션의 요구 사항을 충족하지 않는 경우 채널 또는 수신기를 만들 때 WS_CUSTOM_CHANNEL_BINDING 지정하여 사용자 지정 채널 및 수신기 구현을 정의할 수 있습니다. 채널/수신기의 실제 구현은 WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS 또는WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS 속성을 통해 콜백 집합으로 지정됩니다. 사용자 지정 채널 또는 수신기가 만들어지면 결과는 기존 API 와 함께 사용할 수 있는 WS_CHANNEL 또는 WS_LISTENER 개체입니다.

사용자 지정 채널 및 수신기는 서비스 프록시 또는 서비스 호스트를 만들 때 WS_CHANNEL_BINDING 열거형의 WS_CUSTOM_CHANNEL_BINDING 값과 WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS 및 WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS 속성을 지정하여 서비스 프록시 및 서비스 호스트와 함께 사용할 수도 있습니다.

보안

채널을 사용하면 다음과 같은 속성을 통해 작업의 다양한 측면에 사용되는 메모리 양을 제한할 수 있습니다.

이러한 속성에는 대부분의 시나리오에서 보수적이고 안전한 기본값이 있습니다. 기본값 및 수정 사항은 원격 사용자가 서비스 거부를 일으킬 수 있는 잠재적인 공격 벡터에 대해 신중하게 평가해야 합니다.

채널은 다음과 같은 속성을 통해 작업의 다양한 측면에 대한 시간 제한 값을 설정할 수 있습니다.

이러한 속성에는 대부분의 시나리오에서 보수적이고 안전한 기본값이 있습니다. 시간 제한 값을 늘리면 원격 파티가 메모리, 소켓 및 동기 I/O를 수행하는 스레드와 같은 로컬 리소스를 활성 상태로 유지할 수 있는 시간이 증가합니다. 애플리케이션은 기본값을 평가하고 시간 제한을 늘리면 원격 컴퓨터에서 서비스 거부를 일으킬 수 있는 잠재적인 공격 벡터를 열 수 있으므로 주의해야 합니다.

WWSAPI 채널 API를 사용할 때 신중하게 평가해야 하는 다른 구성 옵션 및 애플리케이션 디자인 고려 사항 중 일부는 다음과 같습니다.

  • 채널/수신기 계층을 사용하는 경우 서버 쪽에서 채널을 만들고 수락하는 것은 애플리케이션에 달려 있습니다. 마찬가지로 클라이언트 쪽에서 채널을 만들고 여는 것은 애플리케이션에 달려 있습니다. 각 채널은 메모리 및 기타 제한된 리소스(예: 소켓)를 사용하므로 애플리케이션은 이러한 작업에 상한을 두어야 합니다. 애플리케이션은 원격 당사자에 의해 트리거되는 모든 작업에 대한 응답으로 채널을 만들 때 특히 주의해야 합니다.
  • 채널을 만들고 수락하는 논리를 작성하는 것은 애플리케이션에 달려 있습니다. 각 채널은 메모리 및 소켓과 같은 제한된 리소스를 사용합니다. 애플리케이션은 허용하려는 채널 수에 상한이 있어야 합니다. 또는 원격 당사자가 많은 연결을 만들어 OOM으로 이어져 서비스 거부가 발생할 수 있습니다. 또한 작은 시간 제한을 사용하여 해당 연결에서 메시지를 적극적으로 수신해야 합니다. 메시지가 수신되지 않으면 작업 시간이 초과되고 연결이 해제됩니다.
  • ReplyTo 또는 FaultTo SOAP 헤더를 해석하여 회신 또는 오류를 보내는 것은 애플리케이션에 달려 있습니다. 보안 방법은 "익명"인 ReplyTo 또는 FaultTo 헤더만 적용하는 것입니다. 즉, 기존 연결(TCP, HTTP) 또는 원본 IP(UDP)를 사용하여 SOAP 회신을 보내야 합니다. 회신이 전송되는 주소에 대해 말할 수 있는 당사자가 메시지를 서명하지 않는 한 애플리케이션은 다른 주소에 회신하기 위해 리소스(예: 채널)를 만들 때 매우 주의해야 합니다.
  • 채널 계층에서 수행된 유효성 검사는 보안을 통해 달성된 데이터 무결성을 대체할 수 없습니다. 애플리케이션은 신뢰할 수 있는 엔터티와 통신하고 있는지 확인하기 위해 WWSAPI의 보안 기능을 사용해야 하며, 데이터 무결성을 보장하기 위해 보안에도 의존해야 합니다.

마찬가지로 WWSAPI 메시지 API를 사용할 때 신중하게 평가해야 하는 메시지 구성 옵션 및 애플리케이션 디자인 고려 사항이 있습니다.

  • 메시지의 헤더를 저장하는 데 사용되는 힙의 크기는 WS_MESSAGE_PROPERTY_HEAP_PROPERTIES 속성을 사용하여 구성할 수 있습니다. 이 값을 늘리면 메시지의 헤더에서 더 많은 메모리를 사용할 수 있으므로 OOM이 발생할 수 있습니다.
  • 메시지 개체의 사용자는 중복 항목을 확인하므로 메시지의 헤더 수와 관련하여 헤더 액세스 API가 O(n)임을 인식해야 합니다. 메시지에 많은 헤더가 필요한 디자인은 과도한 CPU 사용으로 이어질 수 있습니다.
  • 메시지의 최대 헤더 수는 WS_MESSAGE_PROPERTY_MAX_PROCESSED_HEADERS 속성을 사용하여 구성할 수 있습니다. 메시지 힙의 크기에 따라 암시적 제한도 있습니다. 이 두 값을 모두 늘리면 더 많은 헤더가 존재할 수 있으므로 헤더 액세스 API를 사용하는 경우 헤더를 찾는 데 필요한 시간이 복잡합니다.