390 likes | 652 Views
Advanced Network Programming. Ren Jiansi renjsv@cug.edu.cn. Java RMI 技术. (Remote Method Invocation ). RMI 基本原理 : RMI 能让一个 Java 程序调用网络中另外一台计算机的 Java 对象的方法,效果就像这个远程计算机上的对象方法在本地机上一样。 RMI 采用客户 / 服务器通信方式 RMI 应用的开发步骤 : 1. 创建 远程接口 远程接口必须继承 java.rmi.Remote 类。
E N D
Advanced Network Programming Ren Jiansi renjsv@cug.edu.cn
Java RMI技术 (Remote Method Invocation )
RMI基本原理: RMI能让一个Java程序调用网络中另外一台计算机的Java对象的方法,效果就像这个远程计算机上的对象方法在本地机上一样。 RMI采用客户/服务器通信方式 RMI应用的开发步骤: 1.创建远程接口 远程接口必须继承java.rmi.Remote类。 接口中方法必须抛出java.rmi.RemoteException异常。 2.创建远程类 实现远程接口 远程类的命名是远程接口类名加上“Impl”(不是必须),例如,远程接口Upper类对应的远程接口实现类名为UpperImpl。
3.创建服务器程序 服务器程序的一大任务就是向rmiregistry注册表注册远程对象。 4.创建客户程序 运行RMI应用: • 启动注册表 start rmiregistry 默认监听1099端口,可使用命令 start rmiregistry 8000监听别的端口如8000 程序中服务器帮定对象和客户查找远程对象都要变更端口rmi://localhost:8000/… 2. 启动服务器程序 start java SimpleServer 3. 启动客户程序 java SimpleClient
例1:开发一个远程方法upperCase(String str),它把客户(调用者)提供的字符串传送给服务者,服务者把它全部转变成大写字符串后返回给客户。 1.创建远程接口 Upper.java import java.rmi.*; public interface Upper extends Remote { String upperCase(String s) throws RemoteException;}
2.创建远程类 UpperImpl.java import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class UpperImpl extends UnicastRemoteObject implements Upper { public UpperImpl() throws RemoteException { } public String upperCase(String s) throws RemoteException { return s.toUpperCase(); //字符串类的方法 } }
3.创建服务器程序 UpperServer.java import java.rmi.*; import javax.naming.*; public class UpperServer{ public static void main( String args[] ){ try { Upper service = new UpperImpl(); Context namingContext=new InitialContext(); namingContext.rebind( "rmi:Upper1", service); System.out.println("服务器注册了一个Upper对象" ); } catch (Exception e) { e.printStackTrace(); } }}
4.创建客户程序UpperClient.java import java.rmi.*; import javax.naming.*; public class UpperClient { public static void main(String[] arg) { String url="rmi://localhost/"; try { Context namingContext=new InitialContext(); Upper service=(Upper)namingContext.lookup(url+"Upper1"); //利用参数“abc”远程调用方法upperCase() System.out.println(service.upperCase("abc")); } catch (Exception e) {e.printStackTrace();} }}
例2: 1.创建远程接口 HelloService.java import java.util.Date; import java.rmi.*; public interface HelloService extends Remote{ public String echo(String msg) throws RemoteException; public Date getTime() throws RemoteException; }
2.创建远程类 HelloServiceImpl.java import java.util.Date; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloServiceImpl extends UnicastRemoteObject implements HelloService{ private String name; public HelloServiceImpl(String name)throws RemoteException{ this.name=name; }
public String echo(String msg)throws RemoteException{ System.out.println(name+":调用echo()方法"); return "echo:"+msg +" from "+name; } public Date getTime()throws RemoteException{ System.out.println(name+":调用getTime()方法"); return new Date(); } }
3.创建服务器程序SimpleServer.java import java.rmi.*; import javax.naming.*; public class SimpleServer{ public static void main( String args[] ){ try{ HelloService service1 = new HelloServiceImpl("service1"); HelloService service2 = new HelloServiceImpl("service2");
Context namingContext=new InitialContext(); namingContext.rebind( "rmi:HelloService1", service1 ); namingContext.rebind( "rmi:HelloService2", service2 ); System.out.println( "服务器注册了两个HelloService对象" ); }catch(Exception e){ e.printStackTrace(); } } }
4.创建客户程序SimpleClient.java import java.rmi.*; import javax.naming.*; public class SimpleClient{ public static void main( String args[] ){ String url="rmi://localhost/"; try{ Context namingContext=new InitialContext(); HelloService service1=(HelloService)namingContext.lookup(url+"HelloService1"); HelloService
service2=(HelloService)namingContext.lookup(url+"HelloService2"); System.out.println(service1.echo("hello")); System.out.println(service1.getTime()); System.out.println(service2.echo("hello")); System.out.println(service2.getTime()); }catch( Exception e){ e.printStackTrace(); } } }
CORBA CORBA(Common Object Request Broker Architecture,公共对象请求代理结构) 是OMG (Object Management Group,对象管理组织)制定的一个基于开放标准的分布式计算解决方案,它的主要目的是支持用户在计算机硬件、操作系统、程序设计语言和网络通信协议异构的情况下方便地开发健壮的、可伸缩的、面向对象的分布式应用。
CORBA和Java都采用面向对象技术,因此,可以很容易地用Java语言开发CORBA应用,或将Java应用以及JavaBean对象集成到CORBA应用环境中;CORBA和Java都适用于开发分布式应用,所不同的是:CORBA偏重于通用的分布式应用开发,而Java注重于WWW环境中的分布式应用开发。 CORBA 采用客户/服务器模式。 CORBA独立于任何编程语言,独立于任何操作系统平台。在Linux中用Java编写的CORBA对象可以与Windows操作系统中用C++编写的CORBA对象通信。 IDL语言是一种接口定义语言。IDL语言不同于所有已有的程序设计语言,它是一种描述性语言,也就是说,用它描述得到的接口是不能直接被编译执行。 IDL独立于任何其他编程语言。
创建CORBA程序的步骤: 1.创建IDL接口 2.创建IDL接口的实现类 3.创建服务器程序 创建并注册CORBA对象 orbd.exe是 JDK提供的一个CORBA的命名服务器程序 4.创建客户程序 运行CORBA程序: 1. 编译IDL接口 idlj -fall HelloService.idl 2. 启动命名服务器程序 start orbd -ORBInitialPort 1050 1050为命名服务器监听的端口
3. 启动服务器程序 start java hello.HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost 4. 运行客户程序 java hello.HelloClient -ORBInitialPort 1050 -ORBInitialHost localhost 例1: 利用Java与CORBA技术开发一个远程方法upperCase(string str),它把客户(调用者)传送来的字符串全部转变成大写字符串后返回给客户。
1.创建IDL接口 UpperModule.idl module UpperModule { interface Upper { string upperCase(in string str); }; };
2.创建IDL接口的实现类UpperImpl.java package UpperModule; public class UpperImpl extends UpperPOA { public UpperImpl() { } public String upperCase (String str) { //返回结果: return str.toUpperCase(); } }
3.创建服务器程序UpperServer.java package UpperModule; import java.io.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import org.omg.CosNaming.NamingContextPackage.*; public class UpperServer { public static void main(String args[]) { try{
// 初始化ORB对象 ORB orb = ORB.init(args, null); // 建立接口实现类UpperImpl对象,并与ORB连接 UpperImpl upperImpl= new UpperImpl(); //取得RootPOA引用,并激活POAManager POA rootpoa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); //取得对象引用 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(upperImpl);
Upper href = UpperHelper.narrow(ref); //获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //绑定对象引用 String name = "Upper"; NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href);
System.out.println("UpperServer ready ...."); // 等待客户调用 orb.run(); } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }
4.创建客户程序UpperClient.java package UpperModule; import java.io.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; public class UpperClient { public static void main(String args[]) { try { String str;
// 初始化ORB对象 ORB orb = ORB.init(args, null); //使用命名服务获得NamingContext。NameService 是所有ORB命名的总称。 org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); //用NamingContextExt代替NamingContext NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //用名称解析对象引用 String name = "Upper";
Upper upper= UpperHelper.narrow(ncRef.resolve_str(name)); //调用远程方法upperCase() str= upper.upperCase("abc"); System.out.println(str); } catch(Exception e) {System.out.println("ERROR : " + e); e.printStackTrace(System.out); } } }
例2: 1.创建IDL接口 HelloService.idl module hello{ interface HelloService{ string sayHello(); }; };
2.创建IDL接口的实现类HelloServiceImpl.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; public class HelloServiceImpl extends HelloServicePOA { public String sayHello() { return "\nHello world !!\n"; }}
3.创建服务器程序HelloServer.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; public class HelloServer { public static void main(String args[]) { try{
//创建和初始化ORB ORB orb = ORB.init(args, null); //获得根POA的引用,并且激活POAManager POA rootpoa =POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); //创建一个HelloServiceImpl对象,并且把它与ORB关联 HelloServiceImpl helloServiceImpl = new HelloServiceImpl();
//获得HelloServiceImpl对象的CORBA类型的对象引用 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloServiceImpl); HelloService href = HelloServiceHelper.narrow(ref); //获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
//把HelloService对象与“HelloService”名字绑定 String name = "HelloService"; NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href); System.out.println("HelloServer ready and waiting ..."); //等待客户端访问HelloService对象 orb.run(); }catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } }}
4.创建客户程序HelloClient.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class HelloClient{ static HelloService helloServiceImpl; public static void main(String args[]){ try{ //创建和初始化ORB ORB orb = ORB.init(args, null);
//获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //获得名为“HelloService”的HelloService对象的远程引用 String name = "HelloService"; helloServiceImpl = HelloServiceHelper.narrow(ncRef.resolve_str(name));
//调用HelloService对象的远程方法 System.out.println(helloServiceImpl.sayHello()); }catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }