计算机的远程通信有很多种方法, RPC 的设计目标是让一台主机(客户端)上的程序能够引用另一台主机(服务端)上对象,并运行它的方法,也就是“跨地址空间的进程间通信”, RMI 是RPC的Java语言实现。
本实例包含5个文件:
// ================= Hello.java ====================
package test.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
远程方法调用接口,定义远程调用方法
*/
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
//================= HelloServer.java =============================
package test.rmi;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
/
服务器端,实现了Hello接口中的方法,用于实现远程调用方法的具体业务逻辑
//================== HelloClient.java ============================
package test.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
/
* 客户端,需要注册服务器并使用jndi
//================= Configur.java =============================
package test.rmi;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/*
* 获取系统运行所需要的配置信息,对应的配置文件名称为config.properties
/*
* 通过key名称获得配置文件的相关信息
//================= config.properties ============================= HelloServer.RegistryServerPort=1111 HelloServer.HelloServerName=HelloServer HelloServer.RegistryServerName=10.31.1.71
源代码目录是e:\MyDoc\JEx\Ex1\src,Eclipse自动生成的class文件在e:\MyDoc\JEx\Ex1\bin(以及包目录)下。 运行方法:
- E:\MyDoc\JEx\Ex1\bin> rmic test.rmi.HelloServer (rmic.exe是$JAVA_HOME/bin里的文件)
生成e:\MyDoc\JEx\Ex1\bin\test\rmi\HelloServer_Stub.class文件(没有生成skeleton文件)
- E:\MyDoc\JEx\Ex1\bin> java test.rmi.HelloServer
Create Registry Server! HelloServer server start!
-
关闭本机的Windows防火墙;
-
copy HelloClient.class, HelloServer_Stub.class, Hello.class, Configur.class, config.properties到另一台机器,运行 java test.rmi.HelloClient ,返回"Hello from lc!"。
要运行Server只需要Hello.class, HelloServer.class, Configur.class, config.properties 4个文件,HelloServer_Stub.class只在客户端需要。
可以看到客户端新建了一个Hello类型的对象,然后调用了这个对象的方法sayHello,而这个对象和方法的定义在另一台主机上。
RMI是一种同步调用方式,也就是说代码运行到"String message = hello.sayHello()"是会阻塞(block),直到服务端返回sayHello的结果,与此相对, JMS 是异步发送消息,客户端发送完消息后不等待结果返回,运行后面的代码。