Java调用OpenDDS过程中踩了很多坑,记录一下。
提纲
1、DDS简介
2、DDS协议的实现产品
3、OpenDDS安装过程
1、DDS简介
DDS指的是Data Distribution Service,也即数据分发服务,是OMG(Object Management Group,对象管理组织)定义的一个数据传输协议。DDS采用发布-订阅的方式来在两个通信对象之间传输数据,也就是说它基于 DCPS(Data-Centric Publish-Subscribe, 以数据为中心的发布订阅)模型。
DDS协议定义了一套QoS(Quality of Service,服务质量)进行数据传输质量的控制。
DDS看上去和kafka等mq系统、mqtt协议等非常类似,但是仔细研究之后发现它和kafka、mqtt有一个核心的区别,这个核心区别用以下的图来展示更为清晰:
从这张图中可以看到,dds中发布者和订阅者只是通过DDS去发现彼此,当订阅者发现了自己需要的发布者后,传输数据的时候就是他们两个之间直接传输数据,而在kafka或者mqtt中不仅是订阅者、发布者彼此发现对方通过kafka,而且发布者和订阅者之间传输数据也是通过kafka或者mqtt进行的。这一点是他们之间的关键区别,其他方面在概念上都非常类似。
2、DDS协议的实现产品
DDS是一个协议规范,基于这个规范有很多公司做出做了对应的软件产品,这些软件产品都实现了DDS协议,主要有以下4种产品:
-
RTI DDS:由美国 RTI 公司开发,支持Windows、Linux、VxWorks等多种操作系统,商用软件,价格相对较高。目前全球范围内超过500个项目都应用了RTIDDS,包括航空、航天、船舶、国防、金融、通信、汽车等领域。
-
OpenSplice DDS: 最初由 Thales 开发,在 2006 年被 PT(Prism Technologies)收购,主要的应用在 Tacticos 项目(Thales 的战斗管理系统)。
-
OpenDDS:由美国OCI公司开发,基于 C++ 实现,是开源软件。 可从http://www.opendds.org/中获得帮助,目前最新的版本是OpenDDS 3.12.1。尽管OpenDDS采用C++语言实现,但也提供JAVA和JMS的开发接口,这意味着JAVA程序开发也可以使用OpenDDS。
-
MilSoftDDS: 由土耳其的 MILSOFT Soft-ware Technologies 公司开发的DDS应用软件。
-
FastDDS:它由 ePromise 公司发布并维护
-
CycloneDDS:它是Eclipse开源的dds方案,
3、OpenDDS安装过程
安装OpenDDS需要准备一些基础软件,分别是:
- (1)Perl的编译器,在windows上可以安装ActivePerl或者StrawberryPerl,这两个都是Perl语言的windows编译器。Perl编译器的作用是OpenDDS中有很多Perl脚本需要执行。
- (2)Visual Studio Community 2017,vs主要用来对Tao和OpenDDS进行编译。
- (3)JDK8,OpenDDS只支持JDK8,JDK8以后的JDK版本都不支持。
安装OpenDDS是从源代码编译安装,它没有二进制的安装包。编译安装过程中需要编译两个东西,一个是ACE+TAO,第二个是OpenDDS。这两个都可以从OpenDDS官网(http://www.opendds.org/)下载到。
安装的过程其实就是编译Ace+Tao和OpenDDS的过程。
各个软件的版本如下:
- strawberry-perl-5.32.1.1-64bit.msi
- Visual Studio Community 2017
- ACE+TAO-6.5.3.zip
- OpenDDS-3.13.zip
3.1 StrawberryPerl的安装
Perl本来是Linux下一个脚本编程语言,后来有开发者为Perl做了Windows下的解释器,所以Perl语言写的脚本也可以在Windows下运行了,目前据我所知Windows下有两种perl的解释器,分别是activePerl和strawberry-perl,这里我们用的strawberry-perl,所以安装strawberry-perl。
strawberry-perl-5.32.1.1-64bit.msi的安装就是下一步下一步,没有特别的设置,很简单,就不多说了。
安装完成后,打开cmd,输入perl -v查看strawberry perl的版本,如果这个命令顺利输出了strawberry perl的版本,说明strawberry perl安装成功了。
3.2 Visual Studio Community 2017的安装
visual studio community的安装也是下一步下一步的,但是中间有一个地方需要注意,如下两图所示:
把弹出窗口右边的滚动条下拉一下,下面还有需要注意的选项:
这一处选择后,就没有其他需要注意的地方了,其他都是下一步下一步直到完成,就安装成功了。
3.3 ACE+TAO的编译安装
因为ace+tao和opendds是压缩包,所以首先解压。为了统一在一个目录下工作,于是新建一个目录E:\dds
将ACE+TAO-6.5.3.zip 和 OpenDDS-3.13.zip 解压到E:\dds。
进入E:\dds\ACE_wrappers\ace目录,新建一个文件config.h并添加内容:
#include “ace/config-win32.h”
添加环境变量
下面每一个环境变量都不能少。
我踩过坑的,当时我少写了几个环境变量,编译ace+tao的时候死活过不去,查资料查资料浪费了很多时间走了很多弯路,最后才搞明白,过程中又着急又苦恼,唉,苦不堪言。
最后实在没办法,找了一个公司内部搞C++的,结果这哥们来了之后,盲目的拿着鼠标胡摆了几下,走了,我一看完蛋了,这哥们对openDDS一窍不通,完全不懂,就别指望他了,还是自己继续苦干吧。
再后来终于找到一个同事,他是懂openDDS的,他也理解我的难处,我一说他就知道我在哪里卡住了,当时困扰了好几天的苦恼被人一瞬间理解,莫名的产生了一种幸福感,真是有种他乡遇故知的感动。
在和他反复交流过几次之后,终于知道问题是少了几个环境变量,而且他还建议我为了安全起见把perl从activePerl换成strawberryPerl。我被那几天编译出错误折磨的已经够呛了,所以他说啥我听啥,就马上卸载了activePerl,下载strawberryPerl,赶紧安装strawberryPerl,增加环境变量,最后终于把ace+tao给编译好了。
那一刻,我真是长出了一口气,感觉天似乎突然明亮了很多,我呆立在原地看了好久那久违的明亮,感觉好像死过的人,重新回到阳间,重见光明一样,不知道是什么心情,反正是呆呆立了好久,才回过神来。心里难过之余,又痛恨网络上这些文章的作者不把细节写清楚,又感慨研发这工作太tm苦了,苦楚无法言说。最令人可恨的是官方网站写的又简略又没有可落地性,官网都说不明白,还搞个球呀,可是任务在身,不搞能行吗???
写博客的此时,真是感觉往事不堪回首呀!
ACE_ROOT E:\dds\ACE_wrappers
TAO_ROOT %ACE_ROOT%\TAO
MPC_ROOT %ACE_ROOT%\MPC
DDS_ROOT E:\dds\OpenDDS-3.14
LD_LIBRARY_PATH %DDS_ROOT%\lib
PERL5LIB %DDS_ROOT%\bin\PerlDDS
在Path中添加:中添加:
%ACE_ROOT%\lib
%ACE_ROOT%\bin
%DDS_ROOT%\lib
%DDS_ROOT%\bin
编译ACE和TAO
进入到%ACE_ROOT%目录下,可以看到有几个类似于ACE_vs2017.sln的文件,因为我们安装的是VS2017,所以我们用visual studio打开ACE_vs2017.sln,然后依次执行“项目-重新解决方案目标”和“生成-生成解决方案”两个命令,这两个命令都成功执行后,就表示ace编译成功了。
进入到%ACE_ROOT%\TAO目录下,可以看到有几个类似于TAO_ACE_vs2017.sln的文件,同理因为我们安装的是VS2017,所以我们用visual studio打开TAO_ACE_vs2017.sln,同样依次执行“项目-重新解决方案目标”和“生成-生成解决方案”两个命令,这两个命令都成功执行后,就表示tao_ace编译成功了。
3.4 OpenDDS的编译安装
了让OpenDDS支持Java,需要将%JAVA_HOME%\include中的jni.h文件和%JAVA_HOME%\include\win32中的jawt_md.h、jni_md.h复制到Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC下各个版本SDK的include下,以防止编译时找不到这些文件。
进入到%DDS_ROOT%目录下,打开configure文件,找到420行,在420行下面添加下面一行代码:
$opts{‘compiler_version’} = “vs2017”;
用VS2017的开发人员命令提示符,进入%DDS_ROOT%目录,执行./configure --java。
执行后生成了DDS.sln和setenv.cmd两个文件,在命令行执行setenv.cmd设置环境变量。
用Visual Studio 2017 打开 DDS.sln。
打开DDS.sln后,在Visual Studio 2017的解决方案管理器中会看到,这个DDS解决方案包含很多个项目,其中有一个项目Messager_Minimal_Idl是默认选中的。
此时,右键此项目,打开属性窗口,配置属性 > VC++目录 > 常规 > 包含目录中添加
E:\dds\OpenDDS-3.13
E:\dds\ACE_wrappers
E:\dds\ACE_wrappers\TAO
如上图在红色线标出来的位置添加以上的3个目录。
最后,一切设置完毕后,开始编译了。
依次执行“项目-重新解决方案目标”和“生成-生成解决方案”两个命令,这两个命令都成功执行后,就表示openDDS编译成功了。一般而言按照我的步骤设置之后,肯定会成功的,如果有例外没有成功的,我也没办法,自己看着办吧。
3.5 测试OpenDDS的编译是否成功
进入%DDS_ROOT%\java\tests下,这个tests目录中存放的都是java编的dds示例程序,有好多,如下图所示:
网上说进入到这个目录后,就开始执行run_test.pl,网上这些说法都是忽略了中间步骤的,不知道是故意捣鬼还是无意的,反正你直接从tests目录下是找不到run_test.pl的。
因为java/tests/下每一个文件夹都是一个java调用dds的示例程序,而且每一个文件夹下都有run_test.pl,究竟应该执行哪一个呢?
我是进入了messager目录执行了run_test.pl,最后命令执行完,输出了test passed,我知道成功了。
执行run_test.pl命令后,会输出很多东西,但是等一会儿,最后会出现test passed:
这就是编译工作完全成功了。
参考资料:
1、https://blog.csdn.net/wyc12306/article/details/79577292
2、https://blog.csdn.net/zhuwinmin/article/details/117077587
3、https://download.objectcomputing.com/OpenDDS/OpenDDS-latest.pdf,OpenDDS的开发指南
4、https://www.icode9.com/content-4-173582.html