Up:[[Tutorial]] Previous:[[メッセージ送信ツールの作成]] #contents *メッセージ送受信 [#zc25bba0] 前回のメッセージ送信(sendMsg)はサーバを介してコントローラにメッセージを送信しました。 サービスプロバイダはサーバを介さず直接コントローラへメッセージを送信することもできます。 //ここではコントローラとサービスプロバイダがサーバを介さずにメッセージを送受信するサンプルを紹介します。 **コントローラサンプル [#z5f5cfa5] まずサーバ側でコントローラを作成します。 ServiceTest.cpp #highlight(cpp){{ #include <string> #include "Controller.h" #include "Logger.h" #include "ControllerEvent.h" #define PI 3.141592 #define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 ) using namespace std; class AgentController : public Controller { public: double onAction(ActionEvent &evt); void onRecvMsg(RecvMsgEvent &evt); void onInit(InitEvent &evt); private: BaseService *m_srv; }; void AgentController::onInit(InitEvent &evt) { m_srv = NULL; // サービスプロバイダに接続します m_srv = connectToService("MyService"); } double AgentController::onAction(ActionEvent &evt) { if(m_srv != NULL){ // サービスプロバイダにメッセージを送信します m_srv->sendMsgToSrv("Hello"); } return 1.0; } void AgentController::onRecvMsg(RecvMsgEvent &evt) { // メッセージ送信元とメッセージを取得します std::string sender = evt.getSender(); std::string msg = evt.getMsg(); LOG_MSG(("[%s] %s", sender.c_str(), msg.c_str())); } extern "C" Controller * createController () { return new AgentController; } }} 関数connectToServiceでサービスプロバイダ"MyService"に接続します。 これによりSIGVerseサーバを介さずにコントローラとサービスプロバイダで直接データの送受信を行うことができるようになります。 サービスプロバイダとの接続が完了すると関数sendMsgToSrvでサービスプロバイダ"MyService"にメッセージを送信します。 コントローラはコンパイルしておきます。 コントローラはコンパイルしておきます。(手順省略) $ ./sigmake.sh ServiceTest.cpp **世界ファイル [#e544b184] ロボットだけが登場する世界ファイルを作成します。 ServiceTest.xml #highlight(xml){{ <?xml version="1.0" encoding="utf8"?> <world name="myworld"> <gravity x="0.0" y="-9.8" z="0.0"/> <instanciate class="Robot-nii.xml"> <set-attr-value name="name" value="Robot-nii"/> <set-attr-value name="implementation" value="./ServiceTest.so"/> <set-attr-value name="language" value="c++"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="0.0"/> <set-attr-value name="y" value="65.0"/> <set-attr-value name="z" value="0.0"/> </instanciate> </world> }} **サービスサンプル [#d1d0956b] 次にサービスプロバイダのサンプルです。 クライアント側で前回([[メッセージ送信ツールの作成]])と同じようにVC++2008で新しくプロジェクトを作成し、コードを以下のようにします。 MyService.cpp #highlight(cpp){{ //#include "stdafx.h" #include "SIGService.h" #include <tchar.h> #include <string> // SIGServiceを継承したクラスを作成します class MyService : public sigverse::SIGService { public: MyService(std::string name) : SIGService(name){}; ~MyService(); // メッセージ受信時に呼び出される関数 void onRecvMsg(sigverse::RecvMsgEvent &evt); // 定期的に呼び出される関数 double onAction(); }; MyService::~MyService() { // 切断します this->disconnect(); } double MyService::onAction() { return 1.0; } void MyService::onRecvMsg(sigverse::RecvMsgEvent &evt) { // メッセージ送信元とメッセージを取得します std::string sender = evt.getSender(); std::string msg = evt.getMsg(); // メッセージが"Hello"だった場合コントローラにメッセージを返します if(msg == "Hello") { this->sendMsgToCtr(sender, "Hello! this is MyService"); } } int main(int argc, char** argv) { // クラスMyServiceのインスタンスを作成します MyService srv("MyService"); // unsigned short port = (unsigned short)(atoi(argv[2])); // srv.connect(argv[1], port); // サーバに接続します srv.connect("hostname", <portnum>); // メインループをスタートさせます srv.startLoop(); return 0; } }} サーバ接続時の"hostname"と<portnum>は自分の環境に合わせて置き換えてください。 このサービスプロバイダは常にコントローラからのメッセージを受け付けます。 そしてコントローラから"Hello"というメッセージが届くと"Hello! this is MyService"というメッセージをコントローラに返します。 sendMsgToCtrという関数を使うことによりSIGVerseサーバを介さずに直接コントローラにメッセージを送信することができます。 **実行 [#q3f9c3c1] まずSIGVerseサーバを起動します。 $ sigserver.sh -p 9001 -w ./ServiceTest.xml 次にビューワーでシグバースサーバに接続します。接続が完了したら''"START"ボタンを押す前にサービスプロバイダを起動します。'' サーバ側で [SYS] Service: "MyService" is available と表示されればサービスプロバイダ立ち上げ成功です。 次に"START"ボタンを押してシミュレーションを開始します。 サーバ側で一秒に一回 [MSG] Robot-nii(0.0.0.0) [MyService] Hello! this is MyService と表示されれば成功です。 #highlight(end) Up:[[Tutorial]] Previous:[[メッセージ送信ツールの作成]]