서비스 모델 계층 개요
WWSAPI 서비스 모델 API는 클라이언트와 서비스 간의 통신을 데이터 메시지가 아닌 메서드 호출로 모델링합니다. 클라이언트와 서비스 간의 기존 메시지 교환을 지원하는 채널 계층과 달리 서비스 모델은 클라이언트의 서비스 프록시와 서비스의 서비스 호스트를 통해 통신을 자동으로 관리합니다. 즉, 클라이언트는 생성된 함수를 호출하고 서버는 콜백을 구현합니다.
예를 들어 두 숫자에서 더하기 및 빼기를 수행하는 계산기 서비스를 고려해 보세요. 더하기 및 빼기 작업은 메서드 호출로 자연스럽게 표현됩니다.
서비스 모델은 선언된 메서드 호출로 클라이언트와 서비스 간의 통신을 나타내므로 애플리케이션에서 기본 채널 계층의 통신 세부 정보를 숨겨 서비스를 더 쉽게 구현할 수 있습니다.
서비스 지정
서비스는 해당 메시지 교환 패턴과 네트워크 데이터 표현의 관점에서 지정해야 합니다. 서비스의 경우 이 사양은 일반적으로 WSDL 및 XML 스키마 문서로 제공됩니다.
WSDL 문서는 서비스의 채널 바인딩 및 메시지 교환 패턴을 포함하는 XML 문서인 반면 XML 스키마 문서는 개별 메시지의 데이터 표현을 정의하는 XML 문서입니다.
계산기 서비스와 추가 및 빼기 작업의 경우 WSDL 문서는 다음 예제와 같이 표시될 수 있습니다.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://Example.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing"
xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" targetNamespace="http://Example.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:portType name="ICalculator">
<wsdl:operation name="Add">
<wsdl:input wsaw:Action="http://Example.org/ICalculator/Add"
message="tns:ICalculator_Add_InputMessage" />
<wsdl:output wsaw:Action="http://Example.org/ICalculator/AddResponse"
message="tns:ICalculator_Add_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
마찬가지로 XML 스키마를 다음과 같이 정의할 수 있습니다.
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Add">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="a" type="xs:int" />
<xs:element minOccurs="0" name="b" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="AddResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="result" type="xs:int"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
메타데이터를 코드로 변환
서비스 모델은 이러한 메타데이터 문서를 처리하는 도구로 WsUtil.exe 제공하여 WSDL 파일을 C 헤더 및 원본 파일로 변환합니다.
WsUtil.exe 클라이언트에 대한 클라이언트 쪽 서비스 작업뿐만 아니라 서비스 구현을 위한 헤더 및 원본을 생성합니다.
클라이언트에서 계산기 서비스 호출
서비스 구현과 마찬가지로 클라이언트는 생성된 헤더 또는 헤더를 포함해야 합니다.
#include "CalculatorProxyStub.h"
이제 클라이언트 애플리케이션은 서비스 프록시를 만들고 열어 계산기 서비스와의 통신을 시작할 수 있습니다.
WS_ENDPOINT_ADDRESS address = {0};
WS_STRING uri= WS_STRING_VALUE(L"http://localhost/example");
address.uri = uri;
if (FAILED (hr = WsCreateServiceProxy(WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL, 0, &serviceProxy, error)))
goto Error;
if (FAILED (hr = WsOpenServiceProxy(serviceProxy, &address, NULL, error)))
goto Error;
애플리케이션은 다음 코드를 사용하여 계산기 서비스에서 추가 작업을 호출할 수 있습니다.
if (FAILED (hr = DefaultBinding_ICalculator_Add(serviceProxy, heap, 1, 2, &result, NULL, 0, NULL, error)))
goto Error;
계산기 서비스의 전체 구현은 HttpCalculatorClientExample 의 코드 예제를 참조하세요.
서비스 모델 구성 요소
계산기 예제 내에서 개별 WWSAPI 서비스 모델 구성 요소의 상호 작용은 다음과 같습니다.
- 클라이언트는 서비스 프록시 를 만들고 엽니다.
- 클라이언트는 서비스의 Add 함수를 호출하고 서비스 프록시를 전달합니다.
- 메시지는 헤더의 serialization 메타데이터 및 메타데이터 도구(WsUtil.exe)에서 생성된 원본 파일에 따라 직렬화됩니다.
- 메시지는 채널에 기록되고 네트워크를 통해 서비스로 전송됩니다.
- 서버 쪽에서 서비스는 서비스 호스트 내에서 호스트되며 ICalculator 계약을 수신 대기하는 엔드포인트가 있습니다.
- 서비스는 스텁에서 서비스 모델 메타데이터를 사용하여 클라이언트의 메시지를 역직렬화하고 스텁으로 디스패치합니다.
- 서버 쪽 서비스는 Add 메서드를 호출하여 작업 컨텍스트를 전달합니다. 이 작업 컨텍스트에는 들어오는 메시지에 대한 참조가 포함됩니다.
구성 요소
- 서비스 호스트: 서비스를 호스트합니다.
- 서비스 프록시: 클라이언트가 서비스와 통신하는 방법을 정의합니다.
- 컨텍스트: 서비스 작업에 상태별 정보를 사용할 수 있도록 하기 위한 속성 모음입니다.
- 계약: 서비스의 인터페이스 정의입니다. 예를 들어 ICalculator는 예제 코드에서 계산기 서비스에 대한 계약을 나타냅니다.
- WsUtil.exe: 프록시 및 스텁을 생성하기 위한 서비스 모델 메타데이터 도구입니다.