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:[[メッセージ送信ツールの作成]]  

Front page   Edit Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes