前段时间写过一篇CORBA北向网管对接的文章,但后来不想写了,干脆删掉,今天再系统地写一下。
CORBA和SNMP相比,最大的区别在于:CORBA是基于TCP的,而SNMP是基于UDP的。目前开源的CORBA实现还是有几种的,我选取的是ACE-TAO,版本是"ACE-5.3+TAO-1.3",可以在上下载到。下载过来之后,先解压出来,然后进到ACE_wrappers\ace\目录下,添加一个文件,名为:"config.h",因为ACE默认是不知道用户是在哪个平台下编译的,所以需要用户自己来指定。因为我是在WINDOWS32位的机子上做开发,所以只需要在config.h文件中加入以下的内容即可:
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include "config-win32.h"
#endif
在编译动态库之前,需要先设置两个环境变量:
ACE_ROOT:
D:\ACE-5.3+TAO-1.3\ACE_wrappers\ace
TAO_ROOT:
D:\ACE-5.3+TAO-1.3\ACE_wrappers\TAO\tao
两个环境变量的设置需要根据自己本地情况而言。
接下来要做的就是把.dsw文件放到VC6.0里,让编译器帮助你,把我们所需要的动态库都编译出来,一共需要编译十多个动态库,如下图所示:
细心的朋友会发现,当编译这些动态库时,VC会给出一些提示信息,例如:
--------------------Configuration: CosNotification - Win32 Release--------------------
Invoking TAO_IDL Compiler on .\NotifyExt.idl
idli_a01836.cc
Invoking TAO_IDL Compiler on .\Event_Forwarder.idl
idli_a03928.cc
Invoking TAO_IDL Compiler on .\CosNotifyFilter.idl
idli_a03144.cc
Invoking TAO_IDL Compiler on .\CosNotifyComm.idl
idli_a01552.cc
Invoking TAO_IDL Compiler on .\CosNotifyChannelAdmin.idl
idli_a04088.cc
Invoking TAO_IDL Compiler on .\CosNotification.idl
这些*.idl文件会生成一些.cpp和.h文件,比方说:CosNotification.idl被tao_idl.exe编译之后,会生成CosNotificationC.cpp,CosNotificationS.cpp,CosNotificationC.h,CosNotificationS.h。生成的.cpp和.h在之后的我们自己的应用程序的编译中要用到。至于.idl文件时什么,在接下来的内容中会解释。注意下,编译TAO_CosNotification.dll时会很慢,一定要耐着性子等啊,不要以为VC死了,把它强杀了:)
在动态库编译完成之后,等于说是开发环境已经搭建完成,因为必要的动态库和头文件我们都已经有了,这样我们就可以像调用printf函数一样,调用ACE-TAO库里的函数了。
在编写CORBA分布式程序之前,需要先了解什么是idl文件。IDL(interface definition language),翻译过来就是接口定义语言。因为CORBA是跨平台,跨操作系统,跨开发语言的,所以就必须有一个通用的东西来支撑,这就是IDL。只要用户喜欢,用户可以用C++实现SERVER端,用JAVA实现CLIENT;或者是用JAVA实现SERVER端,用C++实现CLIENT端。甚至用其他开发语言都可以,VB,DELPHI等,只要支持IDL的就行。下面我们就来编写一个简单的IDL文件,用于我要实现的这个CORBA DEMO:
文件取名为:HelloWorld.idl
#ifndef _HELLO_WORLD_H_
#define _HELLO_WORLD_H_
interface HelloWorld
{
long sayHelloWorld(in string inString, out string outString);
};
#endif
其实IDL的语法很简单,只要是懂一点开发的人,都能很容易看懂。比起SNMP的MIB文件,IDL文件是容易理解多了,最起码IDL的语法和开发语言本身的语法看上去差不了多少。
在HelloWorld.idl文件中,我定义了一个interface HelloWorld,用tao_idl.exe编译成.cpp和.h文件之后,就是一个class。如果在interface的外层再加上一个module,那那个module到时候编译出来就是一个namespace。
接着,我们写一个编译HelloWorld.idl文件的脚本:compile.bat,内容为:
tao_idl.exe -GI HelloWorld.idl
pause
现在我们只需要双击compile.bat文件,就可以将HelloWorld.idl文件转换成相应的.cpp和.h文件。
注意,这些文件需要放在同一个目录下。
到这里,IDL文件已经成功生成了.cpp和.h文件。接下来要做的就是将这些文件加入到我们自己的工程中,一开始编译,肯定是一堆错误,尽是一些头文件找不到,路径找不到之类的问题。
接下来就可以编写SERVER端程序了,SERVER端程序,相当于下级网管,主要是接收上级网管的请求,并将操作结果返回。还有一点很重要的功能需要实现,就是消息的主动上报,就和SNMP里的TRAP一样。这个是必需的,因为一旦下级网管有告警或者是什么定制消息需要上报,就要用到通知。也许有人会问,我让上级网管来主动查询也是一样的。但是得明白,首先,没有这么多的系统资源给我们浪费;其次,实时性是必须要考虑的一个非常重要的原因。
CORBA的分布式实现,必须依赖Naming_Service.exe,因为在CORBA中,一个ORB就是一个唯一的对象。这些ORB的信息都是存放在Naming_Service.exe中的。如果你要实现的分布式程序需要用到通知的主动上报功能,你还要启动另外一个进程:Notify_Service.exe,通知的发送必须经过它。Naming_Service.exe和Notify_Service.exe的源码在SDK中都有,需要自己手动去编译。
编写完SERVER端和CLIENT端之后,就可以进行CORBA分布式调用。测试环境的拓扑结构图为:
现在开始测试CORBA分布式,在启动下级网管(SERVER端)之前,必须先启动Naming_Service.exe和Notify_Service.exe这两个进程。因为这个DEMO程序中实现了通知上报功能,所以需要启动Notify_Service.exe。
先启动Naming_Service.exe,再启动Notify_Service.exe,最后启动SERVER.exe:
下级网管(SERVER端)已经部署完成了,现在等待上级网管(CLIENT)的请求。
接着启动上级网管(CLIENT),并发送两次请求。下级网管回了两次响应,并同时发了两次通知消息:
观察下级网管(SERVER)端的情况:
下面是抓包的情况:
上图中以红色框起来的部分,是上级网管连接下级网管的过程。因为CORBA是基于TCP的,所以需要有一个连接过程,也就是TCP经典的三次握手。一旦握上手,那这条消息链路也就建立好了。从上图中,可以很清楚的看出,上级网管(CLIENT)一共调用了两次SayHelloWorld方法,而且在Reply中显示No Exception,说明函数调用成功,没有抛出异常。即便是调用失败,在异常信息中也会有说明,到底是什么原因导致调用失败。通知的上报,是通过push_structured_event函数来发送的,其实就和SNMP的TRAP消息是一样的。这里还要说明一点,Naming_Service.exe和Notify_Service.exe两个进程分别需要分配一个端口号,我为Naming_Service.exe进程分配的端口号是5566,为Notify_Service.exe进程分配的端口号是5577。其实端口号可以随你自己喜欢,只要是合法的,且不是预留的端口号就可以。
总结:
1、首先我要感谢高兄的一句话。记得刚开始研究CORBA的时候,因为自己什么都不会,所以就向高兄要源码。结果高兄说,什么东西都自己去试试,如果我源码直接给你,对你来说是没有一点帮助的。后来想想,还是很对的。
2、多参考资料,包括网上的、源码包中的、前人的一些总结。
阅读(3549) | 评论(0) | 转发(0) |