opendds初入门之对inforepo模式运行探索
opendds的集中模式inforepo一般是在主线程中运行,直接run进行阻塞等待,内部有一系列的资源初始化以及ace和tao的相关底层资源。
业务探索,需要把inforepo的集中模式和UI界面进行配合使用,也就是说ui是主进程,而inforepo需要移到子线程中处理。
补充:opendds下的项目,每个项目下都自带一个可执行脚本run_test.pl,对于测试样例,可以在对应项目生成可执行文件目录下执行perl run_test.pl进行运行演示,观察现象。
C:\Users\LEGION\Desktop\opendds_study\OpenDDS\DevGuideExamples\DCPS\Messenger>perl run_test.pl
C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBDebugLevel 1 -ORBLogFile DCPSInfoRepo.log -o repo.ior -DCPSPendingTimeout 3
InfoRepo PID: 24272
.\.\subscriber.EXE -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile subscriber.log -DCPSPendingTimeout 3
subscriber PID: 25360 started at 2025-07-09 17:36:59
.\.\publisher.EXE -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile publisher.log -DCPSPendingTimeout 3
说明:本次是在理解不完善的角度上考虑实现方案的探索。
1:首先了解一下inforepo的作用,主观理解,还未验证。
这里并不是以tcp的交互方式,而是基于tcp的corba,待实际确定!
2:基于现有主进程的方式,首先进行测试一下相关集中模式的发布订阅。
#基于源代码编译后的产物,内部有demo 可以查看验证结果
#执行 perl run_test.pl 可以直接运行,也可以看到内部自带调用指令。
C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBDebugLevel 1 -ORBLogFile DCPSInfoRepo.log -o repo.ior -DCPSPendingTimeout 3
同时,这个脚本,也是一个很好的命令指令样本。
C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBDebugLevel 1 -ORBLogFile DCPSInfoRepo.log -o repo.ior -DCPSPendingTimeout 3
.\.\subscriber.EXE -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile subscriber.log -DCPSPendingTimeout 3
.\.\publisher.EXE -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile publisher.log -DCPSPendingTimeout 3
可以写入日志进行查看日志,确定一些必要信息。
C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBListenEndpoints iiop://127.0.0.1:12345subscriber.EXE -DCPSInfoRepo iiop://127.0.0.1:12345 -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile subscriber.log -DCPSPendingTimeout 3
publisher.EXE -DCPSInfoRepo iiop://127.0.0.1:12345 -ORBDebugLevel 1 -DCPSDebugLevel 4 -ORBVerboseLogging 1 -DCPSTransportDebugLevel 2 -ORBLogFile publisher.log -DCPSPendingTimeout 3
最后,依赖操作系统自动分配节点的时候,可能发现和中心节点网络交互问题,主机可能多个ip吧。
所以,手动指定客户端ip进行跨主机测试。
#在pub和sub运行时加参数
-DCPSDefaultAddress 192.168.1.161:3333
看到一个差异,集中节点的配置如下两种,有什么区别?
-DCPSInfoRepo corbaloc::192.168.1.161:12345/DCPSInfoRepo 和-DCPSInfoRepo iiop://127.0.0.1:12345有什么区别
corbaloc::192.168.1.161:12345/DCPSInfoRepo 是CORBA对象的“定位名称”,明确指定了对象名称,连接可靠,生产环境推荐。
iiop://127.0.0.1:12345 CORBA的iiop:地址(这是ACE/TAO特定的URL格式),仅指定了IIOP协议下的主机和端口,但没有指定对象名称缺少对象名,依赖默认绑定,可能失败或不确定。 推荐本地测试用。
3:考虑在子线程中运行测试。
核心目的是期望Inforepo的线程和主线程UI界面共存。
这里首先测试在子线程中要启动运行正常。
//这里注意,InfoRepo的启动依赖主线程还是底层的一些资源,最终是ACE_OS::thr_self();和CORBA::ORB_init(argc, argv);加上后处理正常。
//这里注意,函数内定义的线程的局部变量,在不加detach()或者join时,线程出作用域释放,会导致崩溃问题。
#include "DCPSInfoRepoServ.h"#ifdef ACE_AS_STATIC_LIBS
# include <dds/DCPS/InfoRepoDiscovery/InfoRepoDiscovery.h>
#endif#include <iostream>
#include <thread>
int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{std::vector<std::string> args = {"InfoRepoService","-ORBListenEndpoints", "iiop://192.168.1.161:12345"};try {std::thread t([args]() {ACE_OS::thr_self();std::vector<char*> argv_vec;for (auto& s : args)argv_vec.push_back(const_cast<char*>(s.c_str()));int argc = argv_vec.size();char** argv = argv_vec.data();CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);if (!CORBA::is_nil(orb)) {std::cout << "[INFO] ORB_init() 成功" << std::endl;}else {std::cerr << "[ERROR] ORB_init() 返回空对象(CORBA::is_nil)" << std::endl;}// 你也可以测试 resolve_initial_references 是否能继续工作CORBA::Object_var poa_obj = orb->resolve_initial_references("RootPOA");if (!CORBA::is_nil(poa_obj)) {std::cout << "[INFO] RootPOA resolved 成功" << std::endl;}else {std::cerr << "[ERROR] 无法 resolve RootPOA" << std::endl;}InfoRepo infoRepo(argc, argv);//这里是为了接受终端上的一些退出信号做处理吗?InfoRepo_Shutdown ir_shutdown(infoRepo);Service_Shutdown service_shutdown(ir_shutdown);std::cout << "infoRepo has run start.";infoRepo.run();std::cout << "infoRepo has run end.";orb->destroy();});t.join();}catch (InfoRepo::InitError& ex) {std::cerr << "Unexpected initialization Error: "<< ex.msg_ << std::endl;return 1;}catch (const CORBA::Exception& ex) {ex._tao_print_exception("ERROR: DDS DCPS Info Repo caught exception");return 1;}return 0;
}
4:考虑停止的逻辑。
基于UI界面的操作,类似上面的逻辑可以通过控件控制启动。
本来设想的是,基于Inforepo的特性,他需要持久化运行,不应该被停止,因为停止后丢失了先前的发布订阅信息。
但是,领导要求停止,所以考虑一下停止的方案。
所以本身让inforepo停止是不合理的,如果要停止,需要做持久化或者其他方案支持。
但是基于技术的角度,尝试使用停止的测试方案。
可探索,基于inforepo集中模式ior,可以考虑配合imr,iogr,以及inforepo联邦进行业务部署。