サービス モデル レイヤーの概要
WWSAPI サービス モデル API は、データ メッセージとしてではなく、クライアントとサービス間の通信をメソッド呼び出しとしてモデル化します。 クライアントとサービス間の従来のメッセージ交換をサポートするチャネル レイヤーとは対照的に、サービス モデルは、クライアント上のサービス プロキシとサービス上のサービス ホストを使用して通信を自動的に管理します。 つまり、クライアントは生成された関数を呼び出し、サーバーはコールバックを実装します。
たとえば、2 つの数値に対して加算と減算を実行する電卓サービスを考えてみましょう。 加算と減算は、メソッド呼び出しとして自然に表される演算です。
サービス モデルは、クライアントとサービス間の通信を宣言されたメソッド呼び出しとして表すので、基になるチャネル レイヤーの通信の詳細をアプリケーションから隠し、サービスの実装を容易にします。
サービスの指定
サービスは、メッセージ交換パターンとネットワーク データ表現の観点から指定する必要があります。 サービスの場合、この仕様は通常、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では、サービス実装用のヘッダーとソース、およびクライアントのクライアント側サービス操作が生成されます。
クライアントからの Calculator サービスの呼び出し
サービスの実装と同様に、クライアントには生成されたヘッダーまたはヘッダーを含める必要があります。
#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;
アプリケーションは、次のコードを使用して、電卓サービスで Add 操作を呼び出すことができます。
if (FAILED (hr = DefaultBinding_ICalculator_Add(serviceProxy, heap, 1, 2, &result, NULL, 0, NULL, error)))
goto Error;
電卓サービスの完全な実装については、 HttpCalculatorClientExample のコード例を参照してください。
サービス モデル コンポーネント
電卓の例内の個々の WWSAPI サービス モデル コンポーネントの相互作用は次のとおりです。
- クライアントは サービス プロキシ を作成して開きます。
- クライアントはサービスの Add 関数を呼び出し、サービス プロキシを渡します。
- メッセージは、ヘッダー内のシリアル化メタデータと、メタデータ ツール (WsUtil.exe) によって生成されたソース ファイルに従ってシリアル化されます。
- メッセージはチャネルに書き込まれ、ネットワーク経由でサービスに送信されます。
- サーバー側では、サービスはサービス ホスト内でホストされ、ICalculator コントラクトをリッスンするエンドポイントがあります。
- スタブで Service Model メタデータを使用すると、サービスはクライアントからメッセージを逆シリアル化し、スタブにディスパッチします。
- サーバー側サービスは Add メソッドを呼び出し、操作コンテキストを渡します。 この操作コンテキストには、受信メッセージへの参照が含まれています。
コンポーネント
- サービス ホスト: サービスをホストします。
- サービス プロキシ: クライアントがサービスと通信する方法を定義します。
- コンテキスト: 状態固有の情報をサービス操作で使用できるようにするプロパティ バッグ。
- コントラクト: サービスのインターフェイス定義。 たとえば、ICalculator は、コード例の電卓サービスのコントラクトを表します。
- WsUtil.exe: プロキシとスタブを生成するためのサービス モデル メタデータ ツール。