第一个corba服务---Hello World
本节摘要:本节介绍一个corba服务的开发过程,包含服务端和客户端,实现一个打印Hello World的功能。
preparation
1.开发背景介绍
最近项目中一直在做corba的这块东西,项目中是在第三方的产品vbroker的产品上做的开发,再者我也主要是做客户端的调用,服务端用的是C++来实现的,具体的发布和部署过程也不清楚。那我就”不爽啊”,为啥咱就不能写一个corba服务,从定义idl文件到开发再到发布?说来咱就来,当然是从最简单的来了,最开始学习java的时候,第一个程序是打印Hello World。OK,come on,咱就用corba写一个服务,输出Hello World然后打印出来瞧瞧。搜集了网上相关资料,并加以整理和理解,咱的第一个corba服务(采用corba静态调用的方式)就问世了。
至于什么是corba,咱就不介绍了,网上一网一箩筐,corba太高深的咱也介绍不了,就不班门弄斧了。
2.IDL介绍
全称:Interface Description Language
使用Java(TM)编写的API提供基于标准的和CORBA的交互性和连接性。
用于描述接口,类似于PRC的.x文件。接口定义语言类似一个协议,来规定接入对象的行为。
用RPC / COM / CORBA技术来编写分布式系统时都需要接口定义语言(IDL)。
特点:
1、IDL是一种规范语言。
2、IDL看上去很像C语言。
3、OMG IDL的目的是定义接口和精简分布对象的过程。
4、IDL分离对象的接口与其实现。
5、IDL剥离了编程语言和硬件的依赖性。
6、使用IDL定义接口的客户机程序员不知道接口背后的实现细节。
7、IDL提供一套通用的数据类型,并以这些数据类型来定义更为复杂的数据类型。
IDL的语法需要的话可以专门的去学习,这里不是我介绍的重点。
3.idlj命令介绍
idlj命令是把idl文件生成java代码,此命令在JDK的安装目录的bin目录下可以找到
idlj命令的使用语法如下:
idlj [选项] <idl文件>
其中,<idl 文件> 是包含 IDL 定义的文件的名称,而[选项] 是以下所列选项的任一组合。这些选项是可选的,并且可以以任意顺序显示;<idl 文件> 是必须的并且必须显示在最后。
选项:
当然,也有把idl文件生成C++代码的,这里我就不关心了。
还有一些软件公司提供的有实现这种转换的产品,比如borland。
4.idlj生成的桩和骨架介绍
因为我要客户端和服务端都自己来实现,所以我使用的idlj命令的选项为-fall
我使用的idl文件名称为Hello.idl(后面会把详细的idl文件内容列出来),那么我运行的命令为 idlj –fall Hello.idl
idl生成java文件的步骤:
1.打开cmd窗口
2.切换到JDK安装目录下的bin目录
3.把Hello.idl文件拷贝到JDK的bin目录下
4.运行idlj命令,由idl文件生成相应的java文件
运行完成,会在JDK的bin目录下生成一个HelloApp文件夹,HelloApp文件夹包含以下6个java文件:
_HelloStub.java
Hello.java
HelloHelper.java
HelloHolder.java
HelloOperations
HelloPOA.java
5.orbd命令介绍
orbd是用来使客户能够透明地查找和调用持久对象在服务器上应用环境,各个参数如下:
sun关于orbd的介绍文档地址如下:http://download.oracle.com/javase/1.4.2/docs/guide/idl/orbd.html
6.netstat命令介绍
netstat命令是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。
7.开发环境
system:win7 myeclipse:6.5 JDK:1.5 project:java project
8.项目结构
start
1.定义idl文件
文件名称:HelloApp.idl
文件内容:
module HelloApp{
interface Hello{
string sayHello();
};
};
2.生成桩和骨架文件
根据前面介绍的步骤,生成java文件,把生成的HelloApp文件夹拷贝到工程的src目录;
这里生成的文件就不贴出来了,后面会把整个工程上传上去;
3.实现服务端
(1)实现sayHello方法
HelloImpl.java
1 package server; 2 3 import HelloApp.HelloPOA; 4 5 /** 6 * 7 *Module: HelloImpl.java 8 *Description: 服务端实现sayHello()方法 9 *Company: 10 *Version: 1.0.0 11 *Author: pantp 12 *Date: Jul 8, 2012 13 */ 14 public class HelloImpl extends HelloPOA { 15 16 public String sayHello() { 17 return "\nHello World\n"; 18 } 19 20 }
(2)开发启动ORB以及等待远程客户机调用的代码
HelloServer.java
1 package server; 2 3 import org.omg.CORBA.ORB; 4 import org.omg.PortableServer.POA; 5 import org.omg.PortableServer.POAHelper; 6 import HelloApp.Hello; 7 import HelloApp.HelloHelper; 8 import org.omg.CosNaming.NamingContextExt; 9 import org.omg.CosNaming.NamingContextExtHelper; 10 import org.omg.CosNaming.NameComponent; 11 12 /** 13 * 14 *Module: HelloServer.java 15 *Description: 启动服务端的服务 16 *Company: 17 *Version: 1.0.0 18 *Author: pantp 19 *Date: Jul 8, 2012 20 */ 21 public class HelloServer { 22 23 //启动ORB以及等待远程客户机的调用的代码 24 public static void main(String args[]) throws Exception { 25 // -ORBInitialPort 1050 26 args = new String[2]; 27 args[0] = "-ORBInitialPort"; 28 args[1] = "1050";//端口 29 30 // 创建一个ORB实例 31 ORB orb = ORB.init(args, null); 32 System.out.println("server--->11111"); 33 34 // 得到一个RootPOA的引用,并激活POAManager 35 org.omg.CORBA.Object obj=orb.resolve_initial_references("RootPOA"); 36 POA rootpoa = POAHelper.narrow(obj); 37 rootpoa.the_POAManager().activate(); 38 39 System.out.println("server--->22222"); 40 41 // 创建一个HelloImpl实例 42 HelloImpl helloImpl = new HelloImpl(); 43 44 System.out.println("server--->33333"); 45 46 // 从服务中得到对象的引用 47 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl); 48 Hello href = HelloHelper.narrow(ref); 49 50 System.out.println("server--->44444"); 51 52 // 得到一个根名称的上下文 53 org.omg.CORBA.Object objRef = orb 54 .resolve_initial_references("NameService"); 55 NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); 56 57 System.out.println("server--->55555"); 58 59 // 在命名上下文中绑定这个对象 60 String name = "Hello"; 61 NameComponent path[] = ncRef.to_name(name); 62 ncRef.rebind(path, href); 63 64 System.out.println("server--->66666"); 65 66 // 启动线程服务,等待客户端调用 67 orb.run(); 68 } 69 }
4.实现客户端
以桩作为客户端应用程序的基础,客户机建立在桩之上,通过Java IDL提供的名字服务查询服务器,获得远程对象的引用,然后调用远程对象中的方法;
HelloClient.java
1 package client; 2 3 import HelloApp.Hello; 4 import HelloApp.HelloHelper; 5 import org.omg.CORBA.ORB; 6 import org.omg.CORBA.ORBPackage.InvalidName; 7 import org.omg.CosNaming.NamingContextExt; 8 import org.omg.CosNaming.NamingContextExtHelper; 9 import org.omg.CosNaming.NamingContextPackage.CannotProceed; 10 import org.omg.CosNaming.NamingContextPackage.NotFound; 11 12 /** 13 * 14 *Module: HelloClient.java 15 *Description: 客户端的初始化以及调用的代码 16 *Company: 17 *Version: 1.0.0 18 *Author: pantp 19 *Date: Jul 8, 2012 20 */ 21 public class HelloClient { 22 23 static Hello helloImpl; 24 25 static { 26 System.out.println("客户端的初始化配置开始......." + System.currentTimeMillis()); 27 28 // -ORBInitialHost 127.0.0.1 -ORBInitialPort 1050 29 String args[] = new String[4]; 30 args[0] = "-ORBInitialHost"; 31 args[1] = "127.0.0.1";// 服务端的IP地址 32 args[2] = "-ORBInitialPort"; 33 args[3] = "1050";// 服务端的端口 34 35 // 创建一个ORB实例 36 ORB orb = ORB.init(args, null); 37 38 // 获取根名称上下文 39 org.omg.CORBA.Object objRef = null; 40 try { 41 objRef = orb.resolve_initial_references("NameService"); 42 } catch (InvalidName e) { 43 e.printStackTrace(); 44 } 45 NamingContextExt neRef = NamingContextExtHelper.narrow(objRef); 46 47 String name = "Hello"; 48 try { 49 helloImpl = HelloHelper.narrow(neRef.resolve_str(name)); 50 } catch (NotFound e) { 51 e.printStackTrace(); 52 } catch (CannotProceed e) { 53 e.printStackTrace(); 54 } catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) { 55 e.printStackTrace(); 56 } 57 58 System.out.println("客户端的初始化配置结束......." + System.currentTimeMillis()); 59 } 60 61 public static void main(String args[]) throws Exception { 62 // init(); 63 sayHello(); 64 } 65 66 // 客户端的初始化配置 67 /* public static void init() throws Exception { 68 System.out.println("客户端的初始化配置开始......." + System.currentTimeMillis()); 69 70 // -ORBInitialHost 127.0.0.1 -ORBInitialPort 1050 71 String args[] = new String[4]; 72 args[0] = "-ORBInitialHost"; 73 args[1] = "127.0.0.1";//服务端的IP地址 74 args[2] = "-ORBInitialPort"; 75 args[3] = "1050";//服务端的端口 76 77 // 创建一个ORB实例 78 ORB orb = ORB.init(args, null); 79 80 // 获取根名称上下文 81 org.omg.CORBA.Object objRef = orb 82 .resolve_initial_references("NameService"); 83 NamingContextExt neRef = NamingContextExtHelper.narrow(objRef); 84 85 String name = "Hello"; 86 helloImpl = HelloHelper.narrow(neRef.resolve_str(name)); 87 88 System.out.println("客户端的初始化配置结束......." + System.currentTimeMillis()); 89 }*/ 90 91 // 调用corba服务的方法 92 public static void sayHello() { 93 String str = helloImpl.sayHello(); 94 System.out.println(str); 95 } 96 }
5.启动应用程序
1.运行startorbd.bat文件,启动orbd服务
startorbd.bat文件内容如下:
@rem 切换到JDK安装路径下的bin目录 根据本机的环境做相应的更改
cd/d “D:\Program Files\Java\jdk1.5.0_06\bin”
@rem 只有端口和IP是可以变化的,这里的端口和IP是根据HelloServer中的设置来定义的
@rem 1050为命名服务器监听的端口,对应HelloServer中的端口;
@rem 127.0.0.1为服务启动的IP地址,对应HelloServer中的IP地址
orbd -ORBInitialPort 1050 -ORBInitialHost 127.0.0.1
运行批处理文件的截图如下:
2.运行服务端程序
运行HelloServer.java的main方法,console窗口打印的信息如下:
说明:运行本来是没有日志的,是我人为的在代码中加入了一些打印语句
3.运行客户端程序
运行HelloClient.java的main方法,console窗口打印的信息如下
以上完成了corba静态调用的整个过程;
再把 说明.txt 贴出来吧: