假如你想找一个利用面向对象的方法去连接一个client到server,你有两个主要的选择:dcom和corba。dcom是微软的解决方案,并且当你为windows系统写代码时非常有用。在本文中,我们将要研究用corba去解决分布式应用程序问题。
corba概要:
在一个通常的用c++或者java写的面向对象的程序里,程序包含所有应用程序需要用到的类。编译器编译和连接这些对象,当你用new语句初始化对象时,它们被创建在应用程序所在的内存里并且被当作一个简单的过程来执行。
corba是一种技术允许一个client程序调用属于一个server的对象,这个server可以是运行在同一台机器或者是几千里外的机器。在它的最基本的阶段,corba是非常简单的-实例化一个在你的处理内存空间的对象代替你在通常的程序中所做的,你可以实例化这个对象无论在哪一个网络的server上。调用这个对象的方法以及这些方法需要传递的参数被打包成网络包的格式发送到服务器上。这个功能实际上是运行在服务器上,返回结果通过网络传递到调用者。
这种方案的优点是服务器可以作为高效的、共享的资源中心,以server为基础的corba对象可以访问server的数据库和其它服务。当然,它的缺点是速度。每秒调用功能的数目被网络速度严格限制,以便保证其它技术通过网络传输数据,因而,corba不是独仪无二的。dcom,甚至socket都要忍受同样的延迟。
用corba方法特别的方面是可以方便的调用orb(object request broker), orb处理和操作client和server之间的连接。在下面的例子里我们将要用inprise visibroker orb。用visibroker,client和server都用一个叫做osagent的服务,osagent用一个标准的端口(通常是14000)连接client,osagent可以当作一个目录去帮助client的orb去找到一个它要找的对象。
用java设置一个简单的corba的client和server是非常简单的,在下面我们将要看到几段例子代码段去显示这个过程,在接下来的部分我们将要解释代码怎样工作的,我们从关键字"安装"开始。
安装
用文档中的例子代码,除了visibroker orb之外你需要下载sun的jdk1.1,你能下载sdk从http://java.sun.com/products/jdk/1.1/index.html。我们用jdk1.1代替1.2是为了避免和java2的orb冲突。你可以得到visibroker orb从http://www.inprise.com/visibroker/。先装sdk,再装orb。
例子代码
为了创建一个corba server并且让client访问它,你要决定server类将要做什么再开始。在这个例子里我们要用一个非常简单的server类,这个类拥有一个私有的整型变量,在这个类里的一个方法将要增加这个整型变量,并且另一个方法将要允许client访问这个变量的正确值,下面是这个类的接口描述:
//counter.idl
module counter{
interface count
{
void increment();
long getcounter();
};
};
这个类被命名为count,它的两个方法是increment和getcounter,这个类被包含在一个叫counter的模板中,只要你愿意这个模板可以包含好几个不同的类,把这idl代码放在一个叫counter.idl名字的文件中。
为了用这个idl文件,你需要idl2java去运行它,这个工具将要创client和server要用到的类,idl2java产生的client类叫做helper并且被命名为counthelper.java,client用helper类去调用server的功能,idl2java产生的server类叫做implbase并且被命名为_countimplebase.java,你将要执行这些server扩展implbase的方法。
注意:当你在client直接用counterhelper.java类时,当你调用一个counter接口的方法时执行在client的代码是_st_counter.java。这个类调用stub把数据打包发送到server并且返回正确的数据,它同server端的skeleton(是_sk_counter.java,继承与_counterimplbase.java)通信。
客户端代码是非常简单的,下面是你能创建的最小的客户端程序。
// client.java
public class client
{
public static void main(string[] args)
{
counter.count count = null;
org.omg.corba.orb orb = null;
// initialize the orb
orb = org.omg.corba.orb.init();
// bind to the object on the server
count = counter.counthelper.bind(orb, "test");
// call the server functions
count.increment();
system.out.println("current count = " + count.getcounter());
// clean up
count = null;
orb.shutdown();
}
}
在这段代码里你可以看到client实例化orb,绑定helper对象为了连接server,接着开始调用方法,为了编译这段代码,储存文件名为client.java并且输入:
vbjc client.java
另外,为orb可以加入三个jar文件到你的class path中并其用javac编译client(三个jar文件是:vbjorb.jar,vbjapp.jar和vbjtools.jar)
假如你想让客户端代码发现问题并且告诉你,你要修改client.java如下:
// client.java
public class client
{
public static void main(string[] args)
{
counter.count count = null;
org.omg.corba.orb orb = null;
// initialize the orb
try
{
orb = org.omg.corba.orb.init();
}
catch (org.omg.corba.systemexception se)
{
system.err.println("initializtion problem in the orb " + se);
system.exit(1);
}
// bind to the object on the server
try
{
count = counter.counthelper.bind(orb, "test");
}
catch (org.omg.corba.systemexception se)
{
system.err.println("binding problem in the orb " + se);
system.exit(1);
}
try
{
count.increment();
system.out.println("current count = " + count.getcounter());
}
catch (org.omg.corba.systemexception se)
{
system.err.println("increment failure " + se);
system.exit(1);
}
// clean up
try
{
count = null;
orb.shutdown();
}
catch (org.omg.corba.systemexception se)
{
system.err.println("problem with cleanup " + se);
system.exit(1);
}
}
}
当你初始化orb并且绑定到server时你有多个选项:
1.orb可以从命令行中接受并且分析这些选项。
2.你可以设置绑定选项。
3.你可以直接连到一个指定的机器。
下面的代码段为你展示了这三个选项
orb = org.omg.corba.orb.init(args, null);
org.omg.corba.bindoptions bindoptions = new
org.omg.corba.bindoptions();
bindoptions.defer_bind = false;
bindoptions.enable_rebind = true;
count = counter.counthelper.bind(orb, "test", "marshall.iftech.com",
bindoptions);
这是初始化从命令行中接受参数,绑定接受了一个指定的机器名和选项。
在server你需要创建两段代码,一段为了client绑定而且执行count类(count类继承与implbase类),如下所示:
// countimpl.java
public class countimpl extends counter._countimplbase
{
private int c = 0;
public countimpl(string name) {
super(name);
}
public countimpl() {
super();
}
public void increment() {
c = c + 1;
system.out.println(c);
}
public int getcounter()
{
return c;
}
}
这个类不能再少了,它的功能只是实现类里的方法,执行这个类的server代码如下:
// server.java
public class server
{
public static void main(string[] args)
{
org.omg.corba.orb orb = null;
org.omg.corba.boa boa = null;
counter.count count = null;
try
{
orb = org.omg.corba.orb.init(args, null);
}
catch (org.omg.corba.systemexception se)
{
system.err.println("initialization problem in the orb " + se);
system.exit(1);
}
try
{
boa = orb.boa_init();
}
catch (org.omg.corba.systemexception se)
{
system.err.println("initialization problem in the boa " + se);
system.exit(1);
}
try
{
count = new countimpl("test");
boa.obj_is_ready(count);
system.out.println(count + " ready.");
boa.impl_is_ready();
}
catch (org.omg.corba.systemexception se)
{
system.err.println("ready problem " + se);
system.exit(1);
}
}
}
server代码用server.java保存,编译这个serve.java:
? vbjc server.java
现在可以测试了,输入如下命令:
> osagent
? vbj server
将要启动server,输入如下命令:
> osfind
> vbj client
osfind命令将要确认server在运行,osfind列出它能找到的正在运行的server和提供服务的对象。第二个命令执行client,你应该看client和server在屏幕上打印的计数值的最新值,你可以运行多次客户端程序来增加这个计数值。
server代码通过初始化orb开始运行,接着初始化server的boa(basic object adapter),boa的任务是告诉server 的orb什么时候server的类准备好了,接着server实例化一个count对象,命名为"test"并且告诉orb:count对象和server都准备好了。imple_is_ready方法允许server在被外部程序访问以前可以实例化多个对象以及执行其它的初始化。
你能够运行server序在另一台机器上,它应以两种工作方式的一种就行工作。假如client和server在同一个网段,osfind通过广播一个请求可以找到server,假如不在同一个网段,你可以修改客户段代码直接连到server上。
可以在java程序中用corba,下面的代码显示一个非常简单的调用这个例子server的applet:
// buttontest.java
import java.awt.*;
import java.applet.*;
public class buttontest extends applet
{
button b;
counter.count count = null;
org.omg.corba.orb orb = null;
public buttontest()
{
setlayout(new borderlayout());
b = new button("apply");
add("north", b);
// ---------
// bind to the counter
string args[] = new string[10];
args[0] = "test";
try {
orb = org.omg.corba.orb.init();
}
catch (org.omg.corba.systemexception se) {
system.err.println("orb init failure " + se);
system.exit(1);
}
try {
count = counter.counthelper.bind(orb, "test");
}
catch (org.omg.corba.systemexception se) {
system.err.println("orb bind failure " + se);
system.exit(1);
}
}
public void paint(graphics g)
{
long i = count.getcounter();
g.drawstring(" " + i, 50, 50);
}
public boolean action(event ev, object arg)
{
if (ev.target instanceof button)
{
try {
count.increment();
}
catch (org.omg.corba.systemexception se) {
system.err.println("increment failure " + se);
system.exit(1);
}
repaint();
return true;
}
return false;
}
}
保存为button.java并且用下面的命令编译:
> vbjc buttontest.java
现在创建一个简单的web page来调用这个applet,如下:
保存为first.htm文件,用applet viewer运行这个applet:
? appleviewer first.htm
任何一个java程序都可以用这个方法访问corba。
体会
client和server在处理中都运行了orb,orb通过网络帮助client和server互相绑定,帮助传递参数和激活相应的方法。
用corba,server必须在client连接以前运行,当client尝试绑定到server时,它的orb开始同osagent对话, osagent列出server上所有的提供服务对象的名字,默认通信的端口号为14000,osagent知道server在运行。当server开始运行时,orb随机挑选一个端口,并且告诉osagent,接着osagent告诉client的server机器名和orb的端口号,client的orb直接连接到server的端口上,通过它调用所有的方法。
另外,client和server在不同的机器上,但是在同一个网段,则在这个网段里必须有一个osagent在运行,client和server通过广播包互相通信。
还有,client和server在不同的网段中,client则直接连到server,server必须运行一个osagent,当client要连到server时,它首先和osagent对话得到server的orb端口号,接着直接连到server。
总结
从这个例子中,你可以看到基本的corba是非常简单的,仅仅两三行代码需要加到client和server程序中去激活corba,连接好以后,客户和服务器程序用标准的代码进行通信,corba的简易性使它非常容易的创建client/server程序。
闽公网安备 35060202000074号