.NET 和 Java 在技术布局上非常类似,.NET 的远程调用经历了DCOM,.NET Remoting,最后是几乎成了.NET 平台SOA代名词的WCF.WCF的目标在于通过一种通用简单的协议来实现通信,即SOAP。WebService的理念的兴起给远程调用,分布式系统的设计带来了很多新的思想。在互联网出现之后,REST 的架构模式下,.NET 上有ASP.NET WebApi ,使用比WCF更为轻量级的Http协议。Java 这方面,WebService 和 Corba 的争议由来已久。
CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构,通用对象请求代理体系结构)是由OMG组织制订的一种标准的面向对象应用程序体系规范。或者说 CORBA体系结构是对象管理组织(OMG)为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案;OMG组织是一个国际性的非盈利组织,其职责是为应用开发提供一个公共框架,制订工业指南和对象管理规范,加快对象技术的发展。
使用CORBA,用户可以透明地访问信息,并不需要知道信息存在于什么软件中、使用什么硬件平台,以及位于企业网络的什么地方。作为面向对象系统的通信核心,CORBA为今天的计算环境带来了真正的互操作性。
CORBA与JAVA的相互关系
CORBA不只意味着对象请求代理(ORB),它还是非常全面的分布式对象平台。CORBA使JAVA应用可以跨越网络、语言以及操作系统,并为JAVA提供了一组分布服务,如分布式自我观察、动态发现、事务、关系、安全和命名等。
JAVA不仅是一种语言,它还是一个动态代码系统,它对运行对象来说是一个可移植的虚拟机(JVM)。JAVA为开发、管理、发布Client/Server应用提供了更简单的方式。人们可以通过将应用放在一个Web服务器上将这一应用发布给成千上万个用户,而不必关心它的安装和升级。JAVA还非常适合服务器的开发,它可以动态地将服务代码移向最需要它们的地方。
JAVA将会使CORBA对象能够运行在从主机、网络计算机到蜂窝电话等可编程的各种机器上,并简化了大型CORBA系统的代码发布。对客户和服务对象来说JAVA是很理想的编程语言,JAVA内置的多线程、垃圾收集和错误处理使编写健壮的网络对象变得很容易。
这两种对象模型可以很好地相互补充,CORBA处理网络的透明性,JAVA处理实现的透明性,CORBA为JAVA可移植应用环境提供了一个分布式的结构。
下面有一个Corba例子。
1. 搭建项目框架
新建两个项目MyCorbaServer和MyCorbaClient.结构如下:
2.使用idl定义接口
idl 是接口定义语言,关于idl的语法,上一篇已经介绍了。
module CorbaAlgorithm{
typedef double d;
interface Algorithm{
string GetName();
d Add(in d x,in d y);
d Sub(in d x,in d y);
d Mul(in d x,in d y);
d Div(in d x,in d y);
};
};
接口里面涉及了自定义的类型,注意参数要使用in
接下来使用idlj 生成CorbaAlgorithm文件夹下的文件。
idlj -fall Algorithm.idl
如果运行正确会生成下列文件
3.在服务端实现接口
package AlgorithmServer;
import CorbaAlgorithm.AlgorithmPOA;
public class AlgorithmImpl extends AlgorithmPOA {
@Override
public String GetName() {
// TODO Auto-generated method stub
return "Corba is good";
}
@Override
public double Add(double x, double y) {
// TODO Auto-generated method stub
return x + y;
}
@Override
public double Sub(double x, double y) {
// TODO Auto-generated method stub
return x - y;
}
@Override
public double Mul(double x, double y) {
// TODO Auto-generated method stub
return x*y;
}
@Override
public double Div(double x, double y) {
// TODO Auto-generated method stub
try
{
return x / y;
}catch(Exception ex)
{
ex.printStackTrace();
return -100000;
}
}
}
4. 在服务端发布
package AlgorithmServer;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import AlgorithmServer.AlgorithmImpl;
import CorbaAlgorithm.Algorithm;
import CorbaAlgorithm.AlgorithmHelper;
public class AlgorithmServer {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
args = new String[2];
args[0] = "-ORBInitialPort";
args[1] = "1050";//端口
ORB orb = ORB.init(args, null);
System.out.println("server--->01 ORB init started.");
org.omg.CORBA.Object obj=orb.resolve_initial_references("RootPOA");
POA rootpoa = POAHelper.narrow(obj);
rootpoa.the_POAManager().activate();
System.out.println("server--->02 POA has been actived.");
// AlgorithmImpl
AlgorithmImpl algorithmImpl = new AlgorithmImpl();
System.out.println("server--->03 AlgorithmImpl has been created.");
// 从服务中得到对象的引用
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(algorithmImpl);
Algorithm href = AlgorithmHelper.narrow(ref);
System.out.println("server--->04 narrow");
// 得到一个根名称的上下文
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
System.out.println("server--->05 Get context by root name.");
// 在命名上下文中绑定这个对象
String name = "Algorithm";
NameComponent path[] = ncRef.to_name(name);
ncRef.rebind(path, href);
System.out.println("server--->06 object binded.");
// 启动线程服务,等待客户端调用
orb.run();
}
}
5.在客户端调用
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 CorbaAlgorithm.Algorithm;
import CorbaAlgorithm.AlgorithmHelper;
public class AlgorithmClient {
static Algorithm helloImpl;
static {
System.out.println("Client init config stated!-" + System.currentTimeMillis());
// -ORBInitialHost 127.0.0.1 -ORBInitialPort 1050
String args[] = new String[4];
args[0] = "-ORBInitialHost";
args[1] = "127.0.0.1";// 服务端的IP地址
args[2] = "-ORBInitialPort";
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 = "Algorithm";
try {
helloImpl = AlgorithmHelper.narrow(neRef.resolve_str(name));
} catch (NotFound e) {
e.printStackTrace();
} catch (CannotProceed e) {
e.printStackTrace();
} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
e.printStackTrace();
}
System.out.println("Client init config ended!" + System.currentTimeMillis());
}
public static void main(String args[]) throws Exception {
sayHello();
}
public static void sayHello() {
System.out.println(helloImpl.GetName());
System.out.println(helloImpl.Add(3.0,4.5));
System.out.println(helloImpl.Sub(3.0,4.5));
System.out.println(helloImpl.Mul(3.0,4.5));
System.out.println(helloImpl.Div(3.0,4.5));
}
}
6.启动程序
运行server输出如下信息:
server--->01 ORB init started.
server--->02 POA has been actived.
server--->03 AlgorithmImpl has been created.
server--->04 narrow
server--->05 Get context by root name.
server--->06 object binded.
运行client输出如下信息:
Client init config stated!-1421987422309
Client init config ended!1421987422571
Corba is good
7.5
-1.5
13.5
0.6666666666666666
我们看到我们定义的接口顺利调用了!