My First RMI Program
RMI,远程方法调用(Remote Method Invocation)是 Enterprise JavaBeans 的支柱,是建立分布式Java 应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。
RMI 的基础是接口,RMI 构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的远程计算服务和使用它的客户程序
一个正常工作的 RMI 系统由下面几个部分组成:
● 远程服务的接口定义
● 远程服务接口的具体实现
● 桩(Stub)和框架(Skeleton)文件
● 一个运行远程服务的服务器
● 一个 RMI 命名服务,它允许客户端去发现这个远程服务
● 类文件的提供者(一个 HTTP 或者 FTP 服务器)
● 一个需要这个远程服务的客户端程序
下面我们一步一步建立一个简单的 RMI 系统。首先在你的机器里建立一个新的文件夹,以便放置我们创建的文件,为了简单起见,我们只使用一个文件夹存放客户端和服务端代码,并且在同一个目录下运行服务端和客户端。
如果所有的 RMI 文件都已经设计好了,那么你需要下面的几个步骤去生成你的系统:
1、 编写并且编译接口的 Java 代码
2、 编写并且编译接口实现的 Java 代码
3、 从接口实现类中生成桩(Stub)和框架(Skeleton)类文件
4、 编写远程服务的主运行程序
5、 编写 RMI 的客户端程序
6、 安装并且运行 RMI 系统
一 、 接口 远程对象的本地接口声明(RMIOperate.java)
· 该类仅仅是一个接口声明,RMI客户机可以直接使用它,RMI服务器必须通过一个远程对象来实现它,并用某个专有的URL注册它的一个实例。
java.rmi.Remote 接口。
· 除了所有应用程序特定的例外之外,每个方法还必须在 throws 子句中声明 java.rmi.RemoteException(或 RemoteException 的父类)。
/**/
import java.rmi.*;
// RMI本地接口必须从Remote接口派生
public interface Hello extends Remote {
// 接口中的具体方法声明,注意必须声明抛出RemoteException
String helloWorld(String message) throws RemoteException;
} 二、 接口的具体实现 这个类应实现RMI客户机调用的远程服务对象的本地接口,它必须从UnicastRemoteObject继承,构造函数应抛出RemoteException异常。 import java . rmi . * ;
import javax . rmi . PortableRemoteObject ;
public class HelloImpl extends PortableRemoteObject implements Hello {
/* 构造函数 */
public HelloImpl() throws RemoteException {
super();
}
/* 实现本地接口中声明的'helloWorld()'方法 */
public String helloWorld( String message) throws RemoteException {
System.out.println( "我在RMI的服务器端,客户端正在调用'sayHello'方法。 ");
System.out.println( "Hello " + message);
return message;
}
}
三、RMI服务器类
该类创建远程对象实现类HelloImpl的一个实例,然后通过一个专有的URL来注册它。所谓注册就是通过Java.rmi.Naming.bind()方法或Java.rmi.Naming.rebind()方法,将HelloImpl实例绑定到指定的URL上。 import java . rmi . * ;
public class HelloServer {
public static void main( String[] args) {
try {
System.out.println( "开始 RMI Server ...");
/* 创建远程对象的实现实例 */
HelloImpl hImpl = new HelloImpl();
System.out.println( "将实例注册到专有的URL ");
Naming.rebind( "HelloService", hImpl);
System.out.println( "等待RMI客户端调用...");
System.out.println( "");
} catch ( Exception e) {
System.out.println( "错误: " + e);
}
}
}
请注意有关 rebind 方法调用的下列参数:
- 第一个参数是 URL 格式的
java.lang.String,表示远程对象的位置和名字。- 需要将
myhost的值更改为服务器名或 IP 地址。否则,如果在 URL 中省略,则主机缺省值为当前主机,而且在 URL 中无需指定协议(例如“HelloServer”)。 - 在 URL 中,可以选择提供端口号:例如“/
/myhost:1234/HelloServer”。端口缺省值为 1099。除非服务器在缺省 1099 端口上创建注册服务程序,否则需要指定端口号。
- 需要将
- 第二个参数为从中调用远程方法的对象实现引用。
- RMI 运行时将用对远程对象 stub 程序的引用代替由
hImpl参数指定的实际远程对象引用。远程实现对象(如HelloImpl实例)将始终不离开创建它们的虚拟机。因此,当客户机在服务器的远程对象注册服务程序中执行查找时,将返回包含该实现的 stub 程序的对象。
· RMI客户使用java.rmi.Naming.lookup()方法,在指定的远程主机上查找RMI服务对象,若找到就把它转换成本地接口RMIOperate类型。它与CORBA不同之处在于RMI客户机必须知道提供RMI服务主机的URL,这个URL可以通过rmi://host/path或rmi://host:port/path来指定,如果省略端口号,就默认使用1099。 · Java.rmi.Naming.lookup()方法可能产生三个异常:Java.rmi.RemoteException、Java.rmi.NotBoundException、java.net. MalformedURLException,三个异常都需要捕获。 import java . rmi . * ;
public class HelloClient {
public static void main( String[] args) {
// 在服务器端设置安全机制
/*
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
*/
/* 默认为本地主机和默认端口 */
String host = "localhost:1099";
/* 带输入参数时,将host设置为指定主机 */
if (args.length > 0)
host = args[0];
try {
/* 根据指定的URL定位远程实现对象 */
/* “h”是一个标识符,我们将用它指向实现“Hello”接口的远程对象 */
Hello h = (Hello) Naming.lookup( "rmi://" + host + "/HelloService");
System.out.println( "实现“Hello”接口的远程对象: " + h);
System.out.println( "我在客户端,开始调用RMI服务器端的'sayHello'方法");
System.out.println( "欢迎, " + h.helloWorld( "javamxj blog"));
} catch ( Exception ex) {
System.out.println( "错误 " + ex);
}
}
} 五、 编译代码与运行系统: 在MS-DOS环境下,创建一个D:/RMISample目录,把上面4个文件复制到这个目录下,然后在此目录下新建两个文件夹:client和server(把它们分别看作是客户端与服务端)。 (1).编译所有的源代码 D:/RMISample> javac *.java (2).生成客户端存根和服务器框架 D:/RMISample> rmic HelloImpl 这将生成HelloImpl_Stub.class和HelloImpl_Skel.class。 ( 注:如果需要查看这两个类的源代码,可以使用“ rmic -keep HelloImpl”语句) (3).把Hello.class、HelloClient.class、HelloImpl_Stub.class复制到client目录; 把Hello.class、HelloServer.class、HelloImpl_Skel.class、HelloImpl_Stub.class 复制到server目录。 (4).启动RMI注册
D:/RMISample/server>rmiregistry (注: 我是在命令控制台下运行这个系统的,必须开启三个控制台窗口,一个运行RMIRegistry,一个运行服务器,还有一个运行客户端。) (5).运行和调用
● 在服务器上执行HelloServer
D:/RMISample/server>java HelloServer ● 在本地客户机上运行HelloClient
D:/RMISample/client>java HelloClient ● 在远程客户机上运行HelloClient(须指明RMI服务器主机名或IP地址)
java HelloClient 222.222.34.34 运行rmiregistry和server后的结果:
再运行Client后的结果:
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
