1. OpenRTI介绍
一个实现了rti1516、rti1516e以及RTI13标准接口的RTI库。
主要功能包括:
- 简单易用
- C++接口(JAVA提供对应接口,未编码实现)
- 扩展性高
- 实现了RTI标准
- 树层次的服务器结构
- 内存零拷贝
- 仅依赖于c++98编译器/stl或更新版本
2. OpenRTI安装
通常使用cmake组织工程
Linux/Unix环境下编译过程:
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=<prefix> <srcdir>
make
make test
make install
Windows环境编译(cl编译器):
cmake -DCMAKE_INSTALL_PREFIX=<prefix> <srcdir>
cmake --build . --config Release
ctest --build-config Release
cmake --build . --config Release --target INSTALL
3. 依赖
上文所说的只依赖c++98以上的编译器,更准确的说法是RTI核心的服务、完整的测试套件以及客户端程序都只需要依赖c++编译器即可;
RTI的部分可选功能可能依赖其他框架,例如:zlib用于在线压缩;python绑定
4. c++语言版本
1> 一般c++11/c++14或以上版本都可以,cmake3.1+
2> 指定c++版本可以加上编译选项-DCMAKE_CXX_STANDARD=11
5. 平台
支持跨平台!!!如果你的平台不支持,可以安装补丁包
主流的Linux(类Linux)/Windows/MacOS和Solaris都测试通过,可以正常使用;少量平台如HP-UX可能支持不太好
6. 支持的RTI特性
OpenRTI支持HLA1.3、rti1516、rti1516e接口;基础的传输基于tcp/ip(稳定可靠传输),对象模型在rti1516e标准中实现,没有实现更新频率降低的功能
- 联邦管理功能:
1> 连接/断连功能可用
2> 创建/销毁功能可用
3> 加入/退出功能可用
4>显示所有功能可用
5> 同步功能可用
6> 存储/恢复不可用!!
7> 失去连接功能可用 - 声明管理:
1> 对象属性的发布/订阅功能可用
2> 可交互类的发布/订阅功能可用
3> 发布时注册/反注册对象类
4> 发布时开启/关闭交互类 - 对象管理功能:
1> 保留/释放(多个)对象实例名功能可用
2> 注册/发现/删除对象实例功能可用
3> 更新/反射属性值功能可用
4> 发送/接收交互类功能可用
5> 删除本地对象实例功能欠缺!!
6> 属性的内外部处理欠缺!!
7> 请求/提供属性值更新功能可用
8> 更新功能开启/关闭功能欠缺
9> 请求修改/查询/上报对象属性功能欠缺!!
10> 请求修改/查询/上报交互信息功能欠缺 - 控制权管理: 功能欠缺!!
- 时间管理:没有消息撤回的情况下功能可用
- 数据分发:功能欠缺!!
- 服务支持:功能可用
- 管理对象模型:当前存在对象模型的概念但是没有对应的数据和方法
注意点:
1> 通常标准程序不会发现连接丢失,而是由连接丢失服务去发现连接丢失
2> 一旦RTI大使发布发布自身,程序就会被调用不像一般的跟踪订阅。这有助于那些依赖于被调用回调的应用程序,但无助于减少应用程序的负载
7. 使用
OpenRTI有几种使用方式:
1> 最常用的是服务器/客户端的使用场景:一个服务器进程和多个联邦进程分布在同一网络的不同机器上;
2> OpenRTI服务作为一个从属服务挂在到一个父节点的服务上, 这样的话看起来就是所有的OpenRTI都是在同一个树形结构上, 但是消息只会发送到自己本机或子网的从服务上, 不会发送到父节点服务;(不常用)
3> 所有的联邦加入到一个程序中, 然后信息仅仅在该程序中发送/接收, 这是效率最高也是比较容易实现的一种方式
8. 连接到RTI
创建并加入到一个联邦, 达到遵循同一标准相互通信的效果
9. 协议
OpenRTI支持的集中通信协议:
1> rti: 默认的通信方式, 基于TCP/IP
2> thread: 在进程内仅适用共享内存的方式通信
3> rtic: 与rti通信方式相同, 仅在rti通信的基础上做了通信两端发送数据流的数据压缩
4> http: 当前版本并不支持, 仅仅是个设想!! 以后可能会支持
5> pipe: 有名管道的通信方式
6> rtinode: 该用法还处在实验阶段, 相当于启动一个rtinode程序以url的方式定位一个服务, 例如:“rtinode:///FederationExecutionName?listen=rti:///”;
10. 联邦名字和URLs
对于1516e来说有字符串列表, 设置连接参数是比较简单的. 但是RTI13没有, 因此, OpenRTI将联邦执行体名字翻译为urls来做联邦的统一定位:
<protocol>://<address>/<path>/<name>
1> RTI13连接到联邦执行体的方式
ambassador.joinFederationExecution("rti://myserver:3324/JustMine")
2> RTI1516连接到联邦执行体的方式
RTI1516支持字符数组, 连接方式变更为使用键值对的方式=描述url, 支持的Key有以下几种:
protocol=<p> # 协议类型
address=<a> # 地址
host=<a> # 主机地址
hostname=<a> # 主机名
port=<p> # 端口
service=<p> # 服务名
timeout=<t> # 超时时间
url=<u> # url字符串
3> RTI1516e连接到联邦执行体的方式(url方式)
11. 服务
独立的ritnode服务程序: 监听本机14321端口, 接收并应答接入进来的rti连接; 支持的命令行参数:
- -b 后台运行
- -c 配置文件
- -f 启动一个服务监听给定的套接字文件
- -i 监听一个指定的tcp/ip地址, 有效地址为[ip:port]的形式
- -p 指定父节点服务
12. 本地时钟
根据RTI1516e标准, 使用64位整数和64位浮点数表示时钟; 参考例子程序:“tests/rti1516/time/logical-time”
13. 编码
对于所有的二进制通信, OpenRTI总会发送一个初始连接包服务器会回复一个应答, 通常这个数据包中包含了12个字节的固定头; 内容为"OpenRTI/0"和4字节的消息体长度, 消息体是键值对信息, 包含了客户端信息, 其中包含了消息发送的编码方式; 一般情况下客户端和服务器交互时需要根据约定的编码方式处理消息. 初始约定的编码方式后续可以重新约定更改
14. 死锁
OpenRTI尽可能保证对象可重用, 假设所有的组件在同一个进程中, 通常不会出现问题; 可能会出现问题的场景在于多线程操作消息队列的时候
可能出现问题的两种因素:1> 多线程运行rti server 2> 变长数据
15. 发布/订阅机制
发布: 当一个服务节点的状态发生变更时, 会发出一条信息通知其他与其连接的节点告知当前的发布状态
订阅: 与发布类似, 仅发送给那些连接到发布端的节点
16. 对象实例管理
1> 对象实例需要由全局的管理器统一管理. 对象所有者创建和删除对象构成该对象的完整生命周期, 其他非该对象的所有者使用该对象仅仅是保留了对象实例的引用. 当引用计数降为0, 对象实例销毁
2> 对象实例创建的同时也会保留一个唯一的对象实例名
3> 当服务节点不再与任何其他节点存在连接关系的时候, 对象引用会被释放
4> 当联邦异常挂死后, 对象引用会被释放