一 关于环境问题
首先关于corba环境搭建可以参考我之前的文章【程序员笔记】Eclipse下搭建Corba开发环境,而对应的idlj是本身jdk自带的jar包,不需要做更多的操作。
二 关于原理问题
通过idl编写文档需求说明,利用类似于脚手架一样的东西快速的生成客户端的桩代码和服务器端的框架代码,然后客户通过自身需求去建立继续编写代码,最后运行即可。
在本地调用远程方法之后,在传到对应的POA(对象适配器),对象适配器会根据客户端的请求以及自身的POA策略找到适合的伺服对象,从而调用这个伺服对象上对应的方法,然后对应进行返回结果。
三 关于步骤问题
创建CORBA应用程序的过程大体如下:
● 编写IDL接口定义文件;
● 将接口定义文件编译为相应高级语言源代码,产生服务器框架与客户端存根;
● 基于服务器框架,编写服务对象实现程序;
● 基于客户端存根,编写客户对象调用程序;
● 分别编译客户对象和服务对象程序;
● 运行服务对象和客户对象程序;
四 关于实战问题
-
整体的项目结构如下,中间的包中的文件都是通过编译idl文件得到的,实际上需要我们自己动手编写的只有最开始的idl文件和client还有server包里面的文件。
整体的项目结构 CorbaTestImpl
import CorbaTest.GoldbashPOA;
public class CorbaTestImpl extends GoldbashPOA {
public String checkNum(float a) {
for(int j=2;j<(a/2+1);j++){
if(isPrimeNum(j)&&isPrimeNum(a-j)){
return "the number is "+(j-0.0)+" and "+(a-j);
}
}
return "2332";
}
public Boolean isPrimeNum(float num){
for(int i=2;i<(num/2+1);i++){
if(num%i==0){
return false;
}
}
return true;
}
}
3 server
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.POAPackage.AdapterAlreadyExists;
import org.omg.PortableServer.POAPackage.InvalidPolicy;
import org.omg.PortableServer.POAPackage.ObjectAlreadyActive;
import org.omg.PortableServer.POAPackage.ServantAlreadyActive;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;
import CorbaTest.Goldbash;
import CorbaTest.GoldbashHelper;
public class Server {
public static void main(String[] args)throws ServantNotActive, WrongPolicy, InvalidName, AdapterInactive, org.omg.CosNaming.NamingContextPackage.InvalidName, NotFound, CannotProceed, org.omg.CORBA.ORBPackage.InvalidName, AdapterAlreadyExists, InvalidPolicy, ServantAlreadyActive, ObjectAlreadyActive {
args=new String[2];
args[0]="-ORBInitialPort";
args[1]="900";
//初始化orb
ORB orb = ORB.init(args, null);
// 取根POA的引用,并激活POAManager
org.omg.CORBA.Object obj=orb.resolve_initial_references("RootPOA");
POA rootpoa = POAHelper.narrow(obj);
//激活POAManager
rootpoa.the_POAManager().activate();
//创建一个Impl实例
CorbaTestImpl corbatestImpl = new CorbaTestImpl();
//从服务中获得对象的引用
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(corbatestImpl);
Goldbash href = GoldbashHelper.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);
System.out.println("server start ");
//启动等待客户端系统调用
orb.run();
}
}
4 client
package client;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import CorbaTest.Goldbash;
import CorbaTest.GoldbashHelper;
import server.CorbaTestImpl;
public class Client {
static Goldbash corbaTestImpl;
static {
System.out.println("client开启连接server");
//初始化ip和端口号,-ORBInitialHost 127.0.0.1 -ORBInitialPort 900
String args[] = new String[4];
args[0] = "-ORBInitialHost";
//server端的IP地址,在HelloServer中定义的
args[1] = "127.0.0.1";
args[2] = "-ORBInitialPort";
//server端的端口,在HelloServer中定义的
args[3] = "900";
//创建一个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实例化好的实现类
corbaTestImpl = GoldbashHelper.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 {
float a=12;
String str = corbaTestImpl.checkNum(a);
System.out.println(str);
}
}
5 比较重要的一点在于项目启动顺序
要先到自己的本机的jdk的bin目录下执行 tnameserv命令,当出现如下界面之后再依次启动服务器端和客户端。
五 关于idlj问题
这个和corba的整体流程几乎是一样的,只是在最开始编译的时候不需要这么麻烦的设定各种位置,只要在项目的idl文件所在位置直接执行
idlj idlname.idl
在当前目录下就会有我们所需要的这几个文件了,然后放到自己的项目目录下即可。