1. CORBA
1.1 CORBA概述
CORBA全称(Common ObjectRequest Broker Architecture)也就是公共对象请求代理体系结构,是OMG(对象管理组织,一个非盈利性的计算机行业标准协会)制定的一种标准的面向对象应用程序体系规范。其提出是为了解决不同应用程序间的通信,曾是分布式计算的主流技术。
CORBA标准主要分为三个部分,IDL(接口语言)、ORB(对象请求代理)、IIOP(ORB之间的操作协议)。
其结构主要分为三部分:naming service、client side、servant side。它们的关系可以理解成目录(naming service)与章节内容(servant side)的关系,内容需要现在目录里进行注册。
CORBA和Java都采用面向对象技术,并且都适用于开发分布式应用,所不同的是:CORBA偏重于通用的分布式应用开发,而Java注重于WWW环境中的分布式应用开发。
1.2 基础概念
IDL(Interface Definition Language,接口定义语言),它是一种与编程语言无关的对于接口描述的规范,实现跨语言跨环境远程对象调用。CORBA用的就是基于IDL的OMG IDL(对象管理标准化接口定义语言)
CORBA中的“ORB”(ObjectRequest Broker,对象请求代理)是一个中间件/代理,建立起服务端与客户端的关系调用。对象可以在本地也可以在其他服务器上,ORB截获客户的调用操作,并查找实现服务的对象,传递参数,调用方法并返回结果。
GIOP(General Inter-ORB Protocol ,通用对象请求协议),是CORBA用来进行数据传输的协议,针对不同的通讯层有不同的实现。而对于TCP/IP层,其实现名为IIOP(Internet Inter-ORB Protocol),也可以说IIOP是通过TCP协议传输的GIOP数据。
1.3 Demo
1.3.1 过程分析
naming service
ORBD可以理解为ORB的守护进程,其主要负责建立客户端(client side)与服务端(servant side)的关系,同时负责查找指定的IOR(可互操作对象引用,是一种数据结构,是CORBA标准的一部分)。ORBD是由Java原生支持的一个服务,其在整个CORBA通信中充当着naming service的作用。
IOR
IOR是一种数据结构,提供关于类型、协议支持和可用ORB服务的信息。它通常提供获取对象的初始引用的方法,可以是命名服务(naming service)、事务服务(transaction services),也可以是定制的CORBA服务。
Stub生成
Stub有很多种生成方式,如:
(1)获取NameServer然后后通过resolve_str()方法生成(NameServer生成方式)
Properties properties = new Properties();
properties.put("org.omg.CORBA.ORBInitialHost", "127.0.0.1");
properties.put("org.omg.CORBA.ORBInitialPort", "1050");
ORB orb = ORB.init(args, properties);
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
String name = "Hello";
helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));
(2)使用ORB.string_to_object生成(ORB生成方式)
//第一种
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object obj = orb.string_to_object("corbaname::127.0.0.1:1050#Hello");
Hello hello = HelloHelper.narrow(obj);
//第二种
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object obj = orb.string_to_object("corbaloc::127.0.0.1:1050");
NamingContextExt ncRef = NamingContextExtHelper.narrow(obj);
Hello hello = HelloHelper.narrow(ncRef.resolve_str("Hello"));
(3)使用javax.naming.InitialContext.lookup()生成(JNDI生成方式)
ORB orb = ORB.init(args, null);
Hashtable env = new Hashtable(5, 0.75f);
env.put("java.naming.corba.orb", orb);
Context ic = new InitialContext(env);
Hello helloRef = HelloHelper.narrow((org.omg.CORBA.Object)ic.lookup("corbaname::127.0.0.1:1050#Hello"));
1.3.2 Helloworld Demo
如果要开发一个CORBA的Helloworld,创建一个helloworld.idl
//helloworld.idl
module helloworld{ //module对应了java中的package
interface HelloWorld{
string sayHello();
};
};
在java命令行下执行idlj -fall helloworld.idl
将IDL语言翻译成JAVA语言,生成server和client端代码,然后会生成_HelloWorldStub.java(实现了HelloWorld接口)、HelloWorld.java(未实现接口)、HelloWorldHelper.java(包含帮助函数,用于处理通过网络传输的对象)、HelloWorldHolder.java、HelloWorldOperations.java(IDL声明的接口)、HelloWorldPOA.java(server的实现接口)。POA(Portable Object Adapter),是CORBA规范的一部分,该类中的方法可以将对象注册到naming service上。
public class HelloServer {
public static void main(String[] args) throws ServantNotActive, WrongPolicy, InvalidName, AdapterInactive, org.omg.CosNaming.NamingContextPackage.InvalidName, NotFound, CannotProceed {
//指定ORB的端口号 -ORBInitialPort 1050
args = new String[2];
args[0] = "-ORBInitialPort";
args[1] = "1050";
//创建一个ORB实例
ORB orb = ORB.init(args, null);
//拿到RootPOA的引用,并激活POAManager,相当于启动了server
org.omg.CORBA.Object obj=orb.resolve_initial_references("RootPOA");
POA rootpoa = POAHelper.narrow(obj);
rootpoa.the_POAManager().activate();
//创建一个HelloWorldImpl实例
HelloWorldImpl helloImpl = new HelloWorldImpl();
//从服务中得到对象的引用,并注册到服务中
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
HelloWorld href = HelloWorldHelper.narrow(ref);
//得到一个根名称的上下文
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
//在命名上下文中绑定这个对象
String name = "Hello";
NameComponent path[] = ncRef.to_name(name);
ncRef.rebind(path, href);
//启动线程服务,等待客户端调用
orb.run();
System.out.println("server startup...");
}
public class HelloClient {
static HelloWorld helloWorldImpl;
static {
//初始化ip和端口号,-ORBInitialHost 127.0.0.1 -ORBInitialPort 1050
String args[] = new String[4];
args[0] = "-ORBInitialHost";
//server端的IP地址,在HelloServer中定义的
args[1] = "127.0.0.1";
args[2] = "-ORBInitialPort";
//server端的端口,在HelloServer中定义的
args[3] = "1050";
//创建一个ORB实例
ORB orb = ORB.init(args, null);
// 获取根名称上下文
org.omg.CORBA.Object objRef = null;
try {
objRef = orb.resolve_initial_references("NameService");
} catch (InvalidName e) {
e.printStackTrace();
}
NamingContextExt neRef = NamingContextExtHelper.narrow(objRef);
String name = "Hello";
try {
//通过ORB拿到了server实例化好的实现类
helloWorldImpl = HelloWorldHelper.narrow(neRef.resolve_str(name));
} catch (NotFound e) {
e.printStackTrace();
} catch (CannotProceed e) {
e.printStackTrace();
} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
e.printStackTrace();
}
}
public static void main(String args[]) throws Exception {
sayHello();
}
//调用实现类的方法
public static void sayHello() {
String str = helloWorldImpl.sayHello();
System.out.println(str);
}