通信组件可以实现多种程序或者多个线程间的消息通信。从原理上看,一般需要采用网络套接字。因为这样可以实现跨设备的通信。
采用vs2015+qt5.9.8开发一个通信组件。调用方式为
//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;
}