8、Khala的设备间管理+通信
在之前的文档中,我们都是从单个设备的角度进行介绍,但在实际业务中,不同设备间存在交互行为。我们经常需要在一个设备的生命周期中查询另一个设备信息,或者向另一个设备进行通信。因此我们提供了设备管理模块来对不同设备进行查询与通信等交互管理。
目前设备管理模块提供了如下接口:
bool hasNode(uint id);
查询某个id的设备是否已经登录。
bool find(uint id, InfoNodePtr& infoNodePtr);
查询某个id的设备节点对象信息,我们可以通过InfoNodePtr节点对象查询具体节点设备的信息,或者通过InfoNodePtr.send()接口向该设备对象发送消息。
std::vector<uint> getNodeIDs(ObjectType* objectType);
查询符合该类型的所有已登录的设备节点ID,只查询该类型,不支持该类型的派生类型的查询。
std::vector<uint> getNodeIDs(const std::string& type);
查询符合该类型的所有已登录的设备节点ID,只查询该类型,不支持该类型的派生类型的查询。
template<class Type>
std::vector<uint> getAllNodeIDs(Type objectType);
查询符合该类型,或者为该类型的派生类型的所有已登录的设备节点ID,比如灯节点类型LightType,派生了日光灯DayLightType类型,调用getAllNodeIDs(LightType)将会获得所有直接为灯节点类型的ID,和派生于灯节点,如日光灯类型的ID。
template<class Type>
std::vector<uint> getAllNodeIDs(Type* objectType);
查询符合该类型,或者为该类型的派生类型的所有已登录的设备节点ID,传入类型为该类型的指针。
getAllNodeIDs()接口中,参数为ObjectType的派生类型对象或指针,实际只需获得具体的对象类型。因为C++的RTTI机制并不能实现:已知两个对象,判断这两个对象是否存在派生关系。而只能实现已知一个对象和一个具体类型,判断这个对象是否派生于这个具体类型(通过dynamic_cast<Type*>判断指针是否为空)。当然也可以通过反射和RTTI机制实现获取对象的具体类型,但是C++也不支持反射/(ㄒoㄒ)/~~。因此该接口的实现采用泛型的形式,必须通过参数传入具体的类型。所以我尝试实现很久的参数为字符串类型的std::vector<uint> getAllNodeIDs(const std::string& type)接口只能胎死腹中。当然RTTI肯定效率感人,但目前本学渣只会这种实现了/(ㄒoㄒ)/~~。
我们通过建立一个MyManageType的设备类型来测试以上接口。在ObjectType的派生类中,我们通过this->getNodeManager()接口即可获得设备管理模块,并使用以上接口。
在MyManageType类型中,我们实现onGetIDByType的消息事件,通过测试getNodeIDs来获取所有同类型的设备ID,具体实现如下:
bool MyManageType::onGetIDByType(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
//通过getNodeIDs获得所有与该设备类型相同的ID
std::vector<uint> v = this->getNodeManager()->getNodeIDs(
infoNodePtr->getNodeType());
std::stringstream ss;
ss << "Get ID By Type:Ask type:" << infoNodePtr->getNodeType()
<< " . Get ID:";
for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
ss << *it << " ";
}
infoNodePtr->send(ss.str());
return true;
}
我们通过客户端进行测试(./example/testClient/HelloKhalaClient4.py)。我们开启两个客户端,进行login操作,并在其中一个客户端测试idByType消息事件。
此时显示存在两个设备类型为my_manage_type的设备,id分别为(懒得抄)…
我们实现onGetAllIDByObject的消息事件,通过测试getAllNodeIDs来获取所有派生于该类型的设备的ID,具体实现如下:
bool MyManageType::onGetAllIDByObject(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
//创建NodeType类型的对象
NodeType* tmp = new NodeType();
//传入NodeType类型,parameter is NodeType Object
std::vector<uint> v = this->getNodeManager()->getAllNodeIDs(*tmp);
std::stringstream ss;
ss << "Get All ID By Object:Ask Object type:" << tmp->getObjectTypeName()
<< " . Get ID:";
for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
ss << *it << " ";
}
infoNodePtr->send(ss.str());
//记得delete
delete tmp;
return true;
}
同样我们在其中一个客户端测试aIdByObject消息事件。
因为我们查询的是NodeType类型,而我们创建的MyManageType类型继承于NodeType类型,因此依旧会显示这两个my_manage_type类型的id。
我们实现askLogin的消息事件,不同于系统默认的isLogin消息事件,askLogin通过测试hasNode来判断任意指定的id设备是否登录。
bool MyManageType::onAskLogin(khala::InfoNodePtr& infoNodePtr, Json::Value& msg,
khala::Timestamp time){
//获得指定id
uint friendId = msg[KEY_FRIEND_ID].asUInt();
std::stringstream ss;
ss<<"Node ID:"<<friendId;
//查询该id是否登录
if(this->getNodeManager()->hasNode(friendId)){
ss<<" is login!";
}else{
ss<<" is not login!";
}
infoNodePtr->send(ss.str());
return true;
}
同样我们在其中一个客户端测试askLogin消息事件。
我们自身的id为2075756572,因此我们查询另一个客户端的id:313508835,此时显示该id已经登录。
最后我们实现sendMsg消息事件,通过测试find接口,并发送消息进行通信。
bool MyManageType::onSendtoNode(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time){
//懒得输入id了,直接获取自身id
uint myId = infoNodePtr->getId();
khala::InfoNodePtr myInfoNodePtr;
if(this->getNodeManager()->find(myId, myInfoNodePtr)){
//如果自身id已登录(废话),则获取的myInfoNodePtr对象有效,通过该对象发送消息
myInfoNodePtr->send("test manager find success");
}
return true;
}
偷个小懒,自己给自己发消息,通过客户端进行测试。
接收消息成功。实际不同设备间进行通信,只需传入实际设备的id,在根据id调用find()接口,最后通过获取的InfoNodePtr调用send()即可,不同设备间进行通信就这么简单。
8、Khala的设备间管理+通信的更多相关文章
- 1、发布C++实现的TCP网络框架Khala
1.Khala简介 Khala(卡拉)是用C++实现的TCP网络框架.底层采用muduo网络库作为网络IO+线程模型,并封装实现了网络实现与业务逻辑分离的多线程网络框架,具有超时退出.多设备多事件注册 ...
- Intel 80386 微处理器的存储器管理
一.存储器的管理 存储器的管理是一种硬件机制,微处理器在总线地址上对物理存储器进行寻址.但是,为了给程序提供比物理存储器容量更大的空间,就引入了虚拟存储器的概念,它在外存(比如磁盘)的支持 ...
- WebRTC 系列之音频会话管理
WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的 API.W3C 和 IETF 在2021年1月26日共同宣布 WebRTC 1. ...
- SPI总线通信电路设计
数据带宽=(总线频率×数据位宽)÷8 B表示带宽,F表示存储器时钟频率,D表示存储器数据总线位数,则带宽为: B(峰值带宽)=F(时钟频率MHz)×D(总线位数bit)/8 例如,PC-100的SDR ...
- 服务器ipmi远程管理
DELL iDRAC (Integrated Dell™ Remote Access Controller )是 Dell PowerEdge 系列服务器上的远程管理方案, 11代 12代服务器已经集 ...
- FPGA和DSP间基于SRIO的高速通信系统设计
作者:陈婷,岳强,汪洋 解放军信息工程大学 摘要: 现代信号处理系统通常需要在不同处理器之间实现高速数据通信,SRIO协议由于高效率.低延时的特性被广泛使用.本文研究了在FPGA和DSP两种处理器之间 ...
- 【新阁教育】基于EtherNet/IP实现欧姆龙NX系列PLC通信
1.引言 工业以太网协议 (Ethernet/IP) 是由ODVA所开发并得到了罗克韦尔自动化的强大支持.它使用已用于ControlNet和DeviceNet的控制和信息协议 (CIP) 为应用层协议 ...
- 开发一个分布式IM(即时通信)系统!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 这知识学的,根本没有忘的快呀?! 是不是感觉很多资料,点收藏起来爽.看视频时候嗨.读 ...
- CPU与内存的那些事
下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址: ...
随机推荐
- MySql函数应用
-- 当前时间 now(); -- 查询结果串联(逗号) select group_concat(col_name) from table_name;
- winPcap_2_编译环境*注意*
使用WinPcap编程 创建一个使用 wpcap.dll 的应用程序 用 Microsoft Visual C++ 创建一个使用 wpcap.dll 的应用程序,需要按以下步骤: 在每一个使用了库的源 ...
- 读取Webpage表中的内容
nutch将从网页中抓取到的信息放入hbase数据库中,默认情况下表名为$crawlId_webpage,但表中的内容以16进制进行表示,直接scan或者通过Java API进行读取均只能读取到16进 ...
- 网页UI视觉设计规范
- 伪协议触发onbeforeunload
根据MSDN描述,IE的onbeforeunload事件触发条件: 简单点来说就是页面URL发生改变时触发: * 关闭浏览器窗口 * 点击后退.前进.刷新.主页 * 点击链接到新页面 * 调用超链接的 ...
- 当list中有中文,打印的时候显示为字符编码的问题
当list中有中文时,print list显示的会是字符编码,比如: 用str()当然也不行: 在不安装其他包的情况下,目前我知道的解决办法是使用decode('string_escape'),如下:
- Dijkstra算法C#实现及其布线运用
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下是空调布线对Dijkstra算法的运用,采用C#实现. 问题:室内机多台,室外机一台.寻找室内 ...
- js 对url字符转译全解
1.js 对url进行字符解码设计到3个方法 escape , encodeURI , encodeURIComponent eg: var url='http://baidu.com';encode ...
- iOS 面试题集合
ASIDownloadCache 设置下载缓存 它对Get请求的响应数据进行缓存(被缓存的数据必需是成功的200请求): [ASIHTTPRequest setDefaultCache:[ASID ...
- Gson解析复杂JSON对象
例如以下格式JSON: 建立对应的Java对象,注意内部类要定义成静态的 public class HResult { public String total; public String recor ...