前述の注意事項を十分に認識したうえで、MSRSのサービスの構造を探っていきましょう。
MSRSのサービスは、次の7つのコンポーネントから成り立っています。
以降で、これら7つのコンポーネントについて説明します。
サービスには、サービスの名前(Service Identifier)が必要です。
MSRSのサービスは、インターネット上に配置することを前提にしているので、インターネット上でユニークな(ほかのサービスと異なる)名前を付ける必要があります。Webサービスの名前付けに関しては、W3Cがすでに規約を作っているので、MSRSはそれに準拠します。
前回「サービス開発の基礎と流れ」において、VC#のテンプレートを使って、必要最小限のサービス(MyProj)を作りました。このときのサービスの名前は、
http://schemas.tempuri.org/2007/06/myproj.html
です。これはVC#が付けた名前です。
最後尾のmyproj.htmlは、筆者がプロジェクト作成時に記述したプロジェクト名ですが、筆者以外の誰かがこの名前を採用することも考えられます。そこで、このサービスをインターネット上に公開する際には、schemas.tempuri.orgを自分のサーバのIPアドレス(ドメインの名前)に変更します。これでサービス名がユニークなものになります。
次に重要なのは、コントラクト(Contract)です。ここでは、“サービスのコントラクトとは何か”について解説します。
例えば、家族でファミリーレストランへ行ったとします。メニューを開いて「何を食べようかな〜」と考えます。子供はハンバーグ、お母さんはスパゲッティ、お父さんはトンカツ……。
“サービスをファミリーレストラン”に例えると、“コントラクトは、メニュー”に当たります。メニューを見れば、そのレストランが提供する料理について知ることができます。
コントラクトは、サービスが提供するメソッド(オペレーション、アクションなどの場合もある)のアクセス方法を抜粋したファイルなのです。
前回の画面11を見てください。これは、MyProjのコントラクトです。これを見ると、MyProjのメソッドとして、Lookup、Drop、Getがあります。もし、筆者がこのMyProjをインターネット上に公開して、ほかのユーザーが筆者のサービスを使うのであれば、まず、MyProjのコントラクトを調べて、それに記述されているメッセージを使って、サービスMyProjにアクセスします。
つまり、コントラクトをガイドにして、インターネット上に公開されているサービスを利用できるのです。
MSRSのサービスは、インターネット上で使用することを前提にしているので、サービスのコントラクトは、インターネット上を流れます。つまり、コントラクトに対して“ユニークな名前”を付ける必要があります。これをコントラクトのID(Contract Identifier)といいます。ちなみに、VC#のテンプレートに記載されているコントラクトのIDは、サービスの名前と同様にシステムが作ったものです。
続いて、コントラクトの別の機能を紹介します。
前回のシリーズ「解説! ロボット開発環境Robotics Studio」では、LEGOのロボットNXTを動かす際に、マイクロソフトが作成したサービスRoboticsCommon.dllを使用しました。
このサービスは、ロボットに関する通信を制御するサービスです。
例えば、個人のサービス「MyRobotCommon(ここでは、MyRobotCommonと名付けた)」を作る場合、RoboticsCommonのコントラクトを利用して、マイクロソフトの「RoboticsCommon.dll」から筆者個人のサービス「MyRobotCommon.dll」を作成します。
なぜ、このようなサービスの切り売りが可能になるのでしょうか?
なぜなら、プログラム上に記述する関数やプロパティに属性(attribute)を付けることによって、コンパイラに対して、ビルド時の指示を与えることができるからです。属性の与え方については、次回以降の連載において、具体的に解説します。
次に、サービスの状態(state)について解説します。
大学などで制御理論を勉強した人は、「状態空間(state space)」という言葉を知っていると思います。“サービスの「状態」は、状態空間の「状態」と同じ意味を持っています”。
例えば、ロボットの直流モーターの回転角度、回転角速度などは、状態の要素になります。ロボットは多くの状態を持つので、これらを「状態」のプロパティとして定義します。
仮に、ロボットの状態を「state」と名付けたとすると、このロボットのモーターの回転速度を2.3 rad/secとする際は、
state.rotVelocity = 2.3;
などと記述します。これは「状態」が持つ回転速度プロパティ(すなわち、rotVelocity)に対して、2.3という数値を設定したという意味です。
モーターの回転角度の目標値からの偏差は、
error = destAngle - state.rotAngle
と計算します。
以上のように、ロボットの状態を“state”によって一元管理するので、プログラムの記述が簡潔になります。
SOAは、メッセージを交換することによって仕事を遂行します。
ポート(port)とは、“サービスがメッセージを受け取る場所、すなわち、サービスの郵便受け”です。
例えば、筆者のポートAにメッセージが来ると、朝食を食べるためにイスに座る、ポートBにメッセージが来ると大学へ行って講義をする……など。ポートにメッセージを投げ込むと、そのポートに定められている仕事が実行されます。通常、ポートは仕事ごとに分けて設けます。
ポートは仕事に応じて作るので、サービスの規模が大きくなると、ポートの数は増加します。これら複数のポートをまとめたものをポートセット(port set)といいます。
ポートにメッセージが投函(とうかん)されると、そのポートに定められた仕事を遂行します。その仕事を記述するプログラムがハンドラ(handler)です。メッセージの到着を合図に、ハンドラのプログラムがスタートします。
食堂で天丼を注文した場合、ウェイターが注文シートに天丼と書いて、コックが天丼を作ります。この例でいうと、“注文シートはメッセージ”、“コックはハンドラ”ということになります。
通知(notification)は、「組み込み」でいう「割り込み」に当る機能です。しかし、通知は、ソフトウェアレベルの機能なので、ハードウェアの割り込み信号などと比べると、応答速度は遅くなります。
例えば、ロボットが障害物に衝突した場合、バンパーの状態がOFFからONへ変化します。その際、サービスから「通知」の信号が発行されます。この通知は、“ロボットの状態が変化したことをほかのサービスに通知する信号”をいいます。
サービスから通知を受けるためには、あらかじめ、サブスクライブ(subscribe)と呼ばれる手続が必要となります。
サービスは多くの場合、ほかのサービスを使用します。一般的にサービスは、インターネット上に存在するので、あらかじめ、プログラム内に使用するサービスのIDを書き込みます。これをパートナー(partner)といいます。パートナーとは、自分以外のサービスを指名する属性です。
今回は、日常的な例を用いて、サービスを構成するコンポーネントとその働きについて説明しました。いよいよ次回から、プログラム作りのスタートです!(次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.