使用 RJB(Ruby Java Bridge) 实现 Ruby 的CORBA RPC

本文介绍了一种使用Ruby调用CORBA服务的方法。通过Rjb库调用Java实现的CORBA客户端,绕过了直接使用Ruby实现CORBA的难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:需要实现一个以Ruby开发的控制台程序,并提供RPC功能,以CORBA为规范,而CORBA服务端有可能是JAVA/C/C++等语言来实现。

方案1: 使用Ruby的开源类库Rinn(http://sourceforge.net/projects/rinn/)来直接实现CORBA客户端以实现对服务端的调用。(先用其提供的ridl(idl-to-ruby)来生成IDL的客户端Ruby代码。)

方案2: 使用java实现CORBA客户端,再通过Rjb(http://rubyforge.org/projects/rjb/),调用java的CORBA客户端代码。

比较: 方案1 与 方案2 的实现复杂程度差不多, 方案1的开源代码直接用纯Ruby代码实现对接口定义语言(IDL)的解析并实现了IIOP协议下的ruby ORB对象。 我一开始还是比较倾向使用这种方案,因为纯Ruby的实现,可以减少客户端环境的复杂程度,至少只需要有Ruby的运行环境就可以了。但是,该开源项目Rinn似乎很久没有人维护了(最近一次修改是在2001年7月),也没有正式release过。我下载了该代码,试图用它来实现客户端代码,但是遇到了很大的麻烦,代码是基于老的Ruby版本写的,而且还有运行错误,也没有完整的文档说明。最后,放弃了方案1选择了方案2。方案2也需要借助开源的类库:Rjb该项目比较完善,于是下载了rjb-1.0.3开始了我的Ruby-CORBA之旅。

首先介绍一下我的开发环境:

Ruby: ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-mswin32]
下载地址: http://rubyforge.org/frs/?group_id=167

Java:
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)

警告: Rjb-1.0.3还不支持1.4或者之前的版本,否则调用会出现[BUG] Segmentation fault。

我将用一个Demo来说明我是如何使用rjb完成对CORBA服务端调用的。

第一步: 安装 rjb-1.0.3-mswin32.gem
使用命令行: gem install D:/Download/Ruby/rjb-1.0.3-mswin32.gem -y
安装成功将会提示: Successfully installed rjb, version 1.0.3

第二步: 创建 CORBA 的 JAVA 服务端/客户端
创建CORBA应用程序的过程大体如下:
● 编写IDL接口定义文件;
● 将接口定义文件编译为相应高级语言源代码,产生服务器框架与客户端存根;
● 基于服务器框架,编写服务对象实现程序;
● 基于客户端存根,编写客户对象调用程序;
● 分别编译客户对象和服务对象程序;
● 运行服务对象和客户对象程序;

a. 接口定义 (HelloApp.idl)
moduleHelloApp
{
interface Hello
{
stringsayHello(instringvin);
oneway
void shutdown();
};
};

通过Sun提供的将IDL文件编译成Java源代码的工具idlj(jdk1.3.0_01以上版本),为接口定义文件生成客户端存根和服务器框架: idlj -fall Hello.idl

这将在idl文件目录下生成一个 HelloApp 文件夹,其中包含以下文件:
Hello.java
HelloHelper.java
HelloHolder.java
HelloOperations.java
HelloPOA.java
_HelloStub.java

b. 接口实现 (HelloImpl.java)
HelloImpl.java是Hello IDL 接口的实现;每个Hello实例都由一个HelloImpl实例来实现。HelloImpl是_HelloImplBase的子类,_HelloImplBase是由 idlj编译器从示例 IDL 中生成的。
// Theservant--objectimplementation--fortheHello
// example.NotethatthisisasubclassofHelloPOA,whose
// sourcefileisgeneratedfromthecompilationof
// Hello.idlusingj2idl.
package HelloApp;

import org.omg.CORBA.ORB;

public class HelloImpl extends HelloPOA{
private ORBorb;

public void setORB(ORBorb_val){
orb
= orb_val;
}

// implementsayHello(vin)method
public StringsayHello(Stringvin){
return " Hello " + vin;
}

// implementshutdown()method
public void shutdown(){
orb.shutdown(
false );
}
}
// endclass

c. 服务端实现 (Server/HelloServer.java)

package Server;

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 HelloApp.Hello;
import HelloApp.HelloHelper;
import HelloApp.HelloImpl;

public class HelloServer{

public static void main(Stringargs[]){
try {
// createandinitializetheORB
ORBorb = ORB.init(args, null );

// getreferencetorootpoa&activatethePOAManager
POArootpoa = (POA)orb.resolve_initial_references( " RootPOA " );
rootpoa.the_POAManager().activate();

// createservantandregisteritwiththeORB
HelloImplhelloImpl = new HelloImpl();
helloImpl.setORB(orb);
// orb.connect((Object)helloImpl);

// getobjectreferencefromtheservant
org.omg.CORBA.Objectref = rootpoa.servant_to_reference(helloImpl);

// andcastthereferencetoaCORBAreference
Hellohref = HelloHelper.narrow(ref);

// gettherootnamingcontext
// NameServiceinvokesthetransientnameservice
org.omg.CORBA.ObjectobjRef = orb
.resolve_initial_references(
" NameService " );

// UseNamingContextExt,whichispartofthe
// InteroperableNamingService(INS)specification.
NamingContextExtncRef = NamingContextExtHelper.narrow(objRef);

// bindtheObjectReferenceinNaming
Stringname = " HelloApp " ;
NameComponentpath[]
= ncRef.to_name(name);
ncRef.rebind(path,href);

System.out.println(
" HelloServerreadyandwaiting... " );

// waitforinvocationsfromclients
orb.run();
}
catch (Exceptione){
System.err.println(
" ERROR: " + e);
e.printStackTrace(System.out);
}

System.out.println(
" HelloServerExiting... " );

}
// endmain
} // endclass

d. 客户端实现 (Client/HelloClient.java)

package Client;

import java.util.Properties;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;

import HelloApp.Hello;
import HelloApp.HelloHelper;

public class HelloClient{
private HelloremoteHello = null ;

public HelloClient(Stringhost,Stringport)
{
Propertiesprops
= new Properties();
props.put(
" org.omg.CORBA.ORBInitialPort " ,port);
props.put(
" org.omg.CORBA.ORBInitialHost " ,host);
String[]args
= {};
try {
ORBorb
= ORB.init(args,props);
// gettherootnamingcontext
// NameServiceinvokesthetransientnameservice
org.omg.CORBA.ObjectobjRef = orb.resolve_initial_references( " NameService " );
NamingContextExtncRef
= NamingContextExtHelper.narrow(objRef);
// gettheObjectReferenceinNaming
Stringname = " HelloApp " ;
remoteHello
= HelloHelper.narrow(ncRef.resolve_str(name));
}
catch (Exceptione){
e.printStackTrace(System.out);
}
}

public java.lang.ObjectsayHello(Stringname)
{
return this .remoteHello.sayHello(name);
}
}

说明: 客户端通过命名服务器中注册的“HelloApp”查找服务端提供的远程的Hello对象。

e. Ruby 代码实现 (HelloAppClient.rb)

require " rjb "

clientClass
= Rjb:: import ( " Client.HelloClient " )
client
= clientClass.new( " localhost " , " 1050 " )

ret
= client.sayHello( " Ruby " )
putsret.toString

其中Ruby 调用 HelloClient 的 sayHello 方法。还可以用 _invoke 方法来调用该方法。

再编写一个vbs来启动服务:

const SERVER_PORT = " 1050 "
set sh = WScript.CreateObject( " WScript.Shell " )
sh.run(
" tnameserv-ORBInitialPort " + SERVER_PORT)
sh.run(
" javaServer/HelloServer-ORBInitialPort " + SERVER_PORT)

运行:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值