Robotics Studio活用術 はじめて作るサービス

Robotics Studio活用術 はじめて作るサービス(4)

SOAを支える2本柱「ポート」と「ハンドラ」

大川 善邦 工学博士 日本大学工学部非常勤講師/大阪大学名誉教授 2007/10/26

本連載は、マイクロソフトのRobotics Studio企画の第2弾です。今回は、「サービス」の作成に重点を置き解説していきます。一緒にロボットを動かす“サービス”を作成し、ロボット開発の楽しさを実感してください。(編集部)

- PR -

 SOAのサービスは、メッセージを交換することによって処理を進めます。その際にポイントとなるのが、「ポート」「ハンドラ」です。

 ポートとは“メッセージの受け口”、ハンドラとは“そのメッセージに対する動作を定めるプログラム”を指します。

 そこで、今回はSOAを支える2本柱ともいえるポートとハンドラについて解説します。

 前回、Microsoft Visual C# 2005 Express SP1(以下、VC#)のテンプレートを使ってサービスを作り、ロボットの状態を実装し、Visual Programming Language(以下、VPL)から読み出す作業を行いました。

 今回はテンプレートに対して、ポートとハンドラを実装し、VPLを使ってメッセージを投げ込み、ハンドラが正常に動作するかどうかをチェックしてみましょう(注)

注:ここでは、SOAの一般論を展開するのではなくて、マイクロソフトのRobotics Studio(以下、MSRS)におけるプログラムの作り方について述べます。

ポートとポートセット

 一般的に、サービスの規模が大きくなると受信するメッセージは増えるので、当然、それらメッセージを受けるポートの数も増加します。しかし、ポートが増えることでプログラム内に同じ形式の文を繰り返し記述することになり、プログラムの可読性(信頼性)は低下してしまいます。

 この問題を避けるためには、連載第2回「身近な例から学ぶ“サービス”」で説明したように、いくつかのポートをまとめて“ポートセット(port set)”とし、メッセージを一括して受信するようにします。いい換えれば、「一般の家庭のように、1つの郵便受けで家族全員の郵便を受け、そこから郵便を取り出して、家族に分配する」といったイメージです。

 連載第3回「サービスはロボットの状態と連動して動くもの」では、ロボットの状態を処理するプログラムを作りました。その際、VC#のテンプレートに対して状態のプロパティを定義し、Getメソッドを使ってそれらを呼び出してダイアログを表示しました。

 実はこのGetメッセージは、MSRSのポートセットを使って処理を行っていたのです。

 前回は、状態に注目してプログラムを作りましたが、前述のとおり今回は視点を変えてポートセットとハンドラに注目してプログラムを作ります。

メッセージGetを解析する

 まず、VC#を起動して、連載第1回「サービス開発の基礎と流れ」で解説した方法に従って、新規プロジェクト「MyProj2」を作成します。

 作成されたテンプレートを眺めてみてください。前回のようにGetメッセージを処理するプログラムが書き込まれているはずです。

 「早速、プログラムを作成しましょう!」。

と、いきたいところですが、まずはテンプレート内の「Get」を解析することから始めましょう。

ポートセットの宣言

 MyProj2プロジェクトの[ソリューション エクスプローラ]で、MyProj2Types.csをダブルクリックします。

 編集ウィンドウに表示されたプログラムを上から下へたどって、「MyProj2Operation」クラスを見つけてください(ソース1)

ソース1 ポートセットを定義するクラス

 これが、ポートセットを定義するクラスです。ポートセットを定義するクラスには、[ServicePort()]という属性が付いています。

 ソース1の最初のセンテンスは、以下のようになっています。

public class MyProj2Operations : PortSet<DsspDefaultLookup,
 DsspDefaultDrop, Get>

 コロンの左側の“MyProj2Operations”は、ここで使用するポートセットのクラス名です。また、コロンの右側の“PortSet”は、MSRSが定義したクラスの名前です。この記述は「MyProj2Operationsは、MSRSのPortSetクラスを継承している」ことを示します。

 つまり、ここでは3種のメッセージ

  • DsspDefaultLookup
  • DsspDefaultDrop
  • Get

を受け取るポートセット「MyProj2Operations」を定義しているのです。

メッセージのクラス

 次に、MyProj2Types.csのソースを見てください。ソース2のようなGetメッセージを定義しているクラスがあります。

ソース2 Getメッセージを定義するクラス (画像をクリックすると拡大します)

 ポートセットには、複数のメッセージが投函(とうかん)されるので、投函されたメッセージをソートして、おのおのハンドラへ送り込む必要があります。そのため、ポートセットを作るときには、必ずそのポートセットが受け取るメッセージ(厳密にいえば、メッセージのクラス)を定義する必要があります。

 ソース2の最初のセンテンスは、以下のようになっています。

public class Get : Get<GetRequestType, PortSet<MyProj2State, Fault>>

 コロンの左側の“Get”はメッセージに付けた名前であり、コロンの右側の“Get”は、MSRSが定義したクラスです。つまり、MSRSにGetというメッセージのクラスが定義されているので、そのクラスを使ってGetというメッセージを作ったということです。名前が同じなので、混同しないように注意してください。

ポートセットのインスタンス

 次に、[ソリューション エクスプローラ]でMyProj2.csをダブルクリックしてください。

 編集ウィンドウに表示されたプログラムを上から下へたどると、メインのポートを生成するセンテンスがあります(ソース3)

ソース3 メインポートの生成

 ここでは[ServicePort()]属性を付けて、メインポートを生成しています。これで、ポートセットのインスタンス(_mainPort)が作成されるのです。

ハンドラ

 さらに、MyProj2.csを下にたどるとメッセージGetに対するハンドラがあります(ソース4)

ソース4 Getのハンドラ

 メッセージのハンドラに対して、[ServiceHandler()]という属性を付けています。

 最初のセンテンス、

public virtual IEnumerator<ITask> GetHandler(Get get)

によって、GetHandlerというハンドラを登録しています。“GetHandler”はハンドラの名前なので、どのような名前を付けても構いませんが、引数の「(Get get)」は、ハンドラをソートする際の識別子なので変更できません。

 また、メッセージのGetは状態を返すプログラムなので、

get.ResponsePort.Post(_state);

によって、サービスの状態(_state)をResponsePortへ投函します。

 これまでの解析結果からメッセージを作成するに当たって、

  1. Typesファイルにおいて、ポートセットとメッセージのクラスを宣言する
  2. 実行ファイルにおいて、ポートセットのインスタンスを生成する
  3. 実行ファイルにおいて、ハンドラを記述する

という順番でプログラミングを進めることにします。

  • 連載バックナンバー
  • 全記事インデックス
  • 組み込み開発トップ
  • MONOistトップ

スキルアップ/キャリアアップ(JOB@IT)

スポンサーからのお知らせ

- PR -
@IT Sepcial

震災関連・復興支援情報

震災関連・復興支援情報
@IT MONOist/EE Times Japan/環境メディアの製造業技術者向け3メディアを中心に、震災関連/復興支援情報を集めました

次世代エンベデッドコーナー

次世代エンベデッド
“次世代”の組み込み機器を開発するエンジニアを支援するコーナー。新潮流・新技術をインタビューやコラム、解説記事で分かりやすく紹介!

Windows Embeddedコーナー

Windows Embedded
Windows Embedded専門コーナー。Windows Embedded StandardやWindows Embedded CEをはじめとする「Windows Embedded」ファミリの最新動向や技術情報をお届けします!!

Androidコーナー

Android
Android専門コーナー。組み込みデバイスへの適用からアプリケーション開発、イベントレポート、ニュースなどAndroidに関するさまざまな技術情報がここに集結!!

@IT MONOist 求人情報

- PR -