通信组件可以实现多种程序或者多个线程间的消息通信。从原理上看,一般需要采用网络套接字。因为这样可以实现跨设备的通信。
采用vs2015开发一个通信组件。调用方式为
//mylinker.h
#pragma once
#include "hlLinker/SimLinker.h"
namespace hlLinker
{
class mylinker : public CSimLinker
{
public:
mylinker();
virtual ~mylinker();
// 发送数据
void sendMyData();
// 发送事件
void sendMyEvent();
protected:
/*
@brief 想定连接成功
*/
virtual void connected();
/*
@brief 想定断开连接
*/
virtual void disconnected();
/*
@brief 节点加入消息
@param name 节点名称
*/
virtual void nodeJoined(const char* name);
/*
@brief 节点退出消息
@param name 节点名称
*/
virtual void nodeResigned(const char* name);
/*
@brief 仿真准备就绪
*/
virtual void simPrepared();
/*
@brief 接收数据
@param platid 平台id
@param timestamp 时戳,单位:ms
@param id 主题ID
@param data 数据指针
*/
virtual void recvData(unsigned int platid,
double timestamp,
unsigned int id,
const Common::ParameterPtr& data);
/*
@brief 仿真运行
@param simtime 仿真时间,单位:微秒
*/
virtual void onRun(int64 simtime);
/*
@brief 新产生
@param forceid
*/
virtual void forceJoined(unsigned int forceid);
/*
@brief 兵
@param forceid
*/
virtual void forceResigned(unsigned int forceid);
/*
@brief 作战事件
@param platid 平台ID
@param level 事件级别
@param desc 事件描述
*/
virtual void fightEvent(unsigned int platid, int type, int level, const char* desc);
/*
@brief 标图添加消息
@param id 标图ID
*/
virtual void graphicsAdded(unsigned int id);
/*
@brief 标图删除消息
@param id 标图ID
*/
virtual void graphicsRemoved(unsigned int id);
/*
@brief 标图参数改变消息
@param id 标图ID
*/
virtual void graphicsChanged(unsigned int id);
/*
@brief 环境数据改变消息
@param name 参数名称
*/
virtual void envirChanged(const char* name);
/*
@brief 主题注册消息
@param topic 主题名称
*/
virtual void topicRegistered(const char* topic);
/*
@brief 主题注销消息
@param topic 主题名称
*/
virtual void topicUnregistered(const char* topic);
private:
unsigned int iMyTopic;
unsigned int iFigthEvent;
std::string _group;
};
}
//mylinker.cpp
#include "mylinker.h"
#include <iostream>
#include "Utility/OSHelper.h"
#include "Utility/TimeHelper.h"
#include "Utility/JsonFile.h"
#include "Utility/CodeConverter.h"
#include "hlLinker/IEnvir.h"
#include "Topics/basic.h"
#include "Topics/inner.h"
#include "KernelDefine.inl"
namespace hlLinker
{
mylinker::mylinker() {
register_subscribe("Intelligence");
register_subscribe("topic1");
register_publish("topic1");
register_publish("FightEvent");
subscribe_local(false);
iMyTopic = topicid("topic1");
iFigthEvent = topicid("FightEvent");
}
mylinker::~mylinker() {}
void mylinker::sendMyData()
{
Common::ParameterPtr ptr = Common::create(Common::String_TYPE);
char buf[256];
_tsprintf(buf, "hello world:%d", Common::self_pid());
ptr->castStringParser()->setValue(buf);
sendData(0, iMyTopic, ptr);
}
void mylinker::sendMyEvent()
{
Common::ParameterPtr ptr = Common::create(Common::InnerFightEvent_TYPE);
Common::IInnerFightEventParser* event = dynamic_cast<Common::IInnerFightEventParser*>(ptr.get());
event->Desc()->setValue(u8"我的事件");
sendData(0, iFigthEvent, ptr);
}
void mylinker::connected()
{
_group = getScenario()->group();
std::cout << "connect " << _group << " succeed" << std::endl;
IEnvir* envir = getEnvir();
std::cout << "startTime:" << envir->startTime() << std::endl;
std::cout << "endTime:" << envir->endTime() << std::endl;
std::cout << "pressure:" << envir->pressure() << std::endl;
std::cout << "humidityratio:" << envir->humidityratio() << std::endl;
std::cout << "precipitation:" << envir->precipitation() << std::endl;
std::cout << "weather:" << envir->weather() << std::endl;
std::cout << "temperature:" << envir->temperature() << std::endl;
std::cout << "wind:" << envir->wind() << std::endl;
}
void mylinker::disconnected()
{
getScenario()->clear();
join(_group.c_str());
std::cout << "disconnected" << std::endl;
}
void mylinker::nodeJoined(const char* name)
{
std::cout << "new node joined:" << name << std::endl;
}
void mylinker::nodeResigned(const char* name)
{
std::cout << "node resigned : " << name << std::endl;
}
void mylinker::simPrepared()
{
}
void mylinker::recvData(unsigned int platid,
double timestamp,
unsigned int msgid,
const Common::ParameterPtr& data)
{
if (iMyTopic == msgid)
{
std::cout << "MyTopic:" << platid << ":" << timestamp << "-->" << data->castStringParser()->value() << std::endl;
return;
}
unsigned int iIntelligence = topicid("Intelligence");
if (msgid == iIntelligence)
{
Common::IIntelligenceParser* ptr = dynamic_cast<Common::IIntelligenceParser*>(data.get());
ptr->getSrcID();
ptr->getDestID();
ptr->getTime();
ptr->getNumTarget();
ptr->getExplainTarget();
ptr->getIDTarget();
ptr->getExplainTraceTarget();
ptr->getKind();
ptr->getTraceID();
ptr->getIFF();
ptr->getPos();
ptr->getDistanceRtoTMeasure();
ptr->getOrientRtoTMeasure();
ptr->getFormationTarget();
ptr->getDistanceError();
ptr->getOrientAngleError();
ptr->getCodeRespTarget();
ptr->getElevationAngleError();
ptr->getKindTarget();
return;
}
}
void mylinker::onRun(int64 simtime)
{
_tstring stime = Common::formatSimTime(simtime);
_tprintf("\rtime:%s", stime.c_str());
//conduct(R"({"ctrl":{"cmd":"stop"}})");
hlLinker::IntelligencePtrType intells[100];
int len = getScenario()->getIntelligences(3, intells, 100);
if (len > 0)
{
int nTest = 0;
}
}
void mylinker::forceJoined(unsigned int forceid)
{
hlLinker::EntityPtrType pEntity = getEntity(forceid);
if (pEntity)
{
const char* name = pEntity->name();
const char* task = pEntity->getTask();
const char* stocks = pEntity->getStocks();
double lon = pEntity->getLon();
double lat = pEntity->getLat();
int iff = pEntity->getIFF();
char buf[256];
_tsprintf(buf, u8"a new force joined:%u:name:%s:lon:%0.3f:lat:%0.3f:iff:%d:task:%s", forceid, name, lon, lat, iff, task);
std::string strval;
utf82ascii(buf, strval);
std::cout << strval << std::endl;
std::cout << "stocks:" << stocks << std::endl;
int count = pEntity->count();
for (int i = 0; i < count; ++i)
{
int dt = pEntity->dataTypeOfProperty(i);
switch (dt)
{
case Common::Bool_TYPE:
{
break;
}
case Common::Char_TYPE:
{
break;
}
case Common::Int_TYPE:
{
int val = 0;
pEntity->getProperty(i, val);
std::cout << pEntity->nameOfProperty(i) << ":" << val << ";";
break;
}
case Common::UInt_TYPE:
{
break;
}
case Common::Short_TYPE:
{
break;
}
case Common::Float_TYPE:
{
float val = 0;
pEntity->getProperty(i, val);
std::cout << pEntity->nameOfProperty(i) << ":" << val << ";";
break;
}
case Common::Double_TYPE:
{
double val = 0;
pEntity->getProperty(i, val);
std::cout << pEntity->nameOfProperty(i) << ":" << val << ";";
break;
}
case Common::String_TYPE:
{
char val[4098] = { 0 };
int len = 4098;
pEntity->getProperty(i, val, len);
std::cout << pEntity->nameOfProperty(i) << ":" << val << ";";
break;
}
}
}
}
std::cout << std::endl << "=======================================================================" << std::endl;
}
void mylinker::forceResigned(unsigned int forceid)
{
char buf[256];
_tsprintf(buf, "a force resigned:%u", forceid);
std::cout << buf << std::endl;
}
void mylinker::fightEvent(unsigned int platid, int type, int level, const char* desc)
{
std::cout << platid << "-->" << desc << std::endl;
}
void mylinker::graphicsAdded(unsigned int id)
{
hlLinker::GraphicsPtrType graphics = getGraphics(id);
if (graphics)
{
std::cout << graphics->name() << std::endl;
std::cout << graphics->anchors() << std::endl;
}
}
void mylinker::graphicsRemoved(unsigned int id)
{
}
void mylinker::graphicsChanged(unsigned int id)
{
}
void mylinker::envirChanged(const char* name)
{
}
void mylinker::topicRegistered(const char* topic)
{
std::cout << topic << " registered" << std::endl;
}
void mylinker::topicUnregistered(const char* topic)
{
std::cout << topic << " unregistered" << std::endl;
}
}
//main.cpp
#include "mylinker.h"
#include <iostream>
#include "Utility/IniFile.h"
#include "sysdefine.h"
int main(int argc, char* argv[])
{
hlLinker::mylinker linker;
const char* cfgfile = dbdk::sys_config_file();
Common::CIniFile ini;
if (!ini.Open(cfgfile))
{
std::cout << "please install dbdk 4.0 first" << std::endl;
return 0;
}
std::string group;
ini.GetCfgStr("Simulate", "group", group, group);
if (group.empty())
group = "lcfgroup";
if (!linker.join(group.c_str()))
{
return 0;
}
std::cout << "join " << group << " succeed" << std::endl;
while (true)
{
linker.sendMyData();
linker.sendMyEvent();
_tsleep(1);
}
return 0;
}