一、入门篇
Java RMI指的是远程方法调用(Remote Method Invocation). 它是一种机制, 能够让不同操作系统之间程序实现方法调用.
比如: 一台电脑上的Java程序可以通过RMI调用另一台电脑上的方法(EJB底层就是使用RMI).
二、RMI和webservice
RMI是在TCP协议上传递可序列化的Java对象, 只能用在Java虚拟机上, 客户端和服务端必须都是Java.
webservice是在http协议上传递xml文件, 它与语言和平台无关, 可以在异构系统间传递.
对于不同语言间的通讯我们可以考虑用webservice或者公用对象请求代理体系COBRA来实现.
三、RMI的优点
RMI为分布式系统设计、编程带来了遍历. 只要按照RMI规则设计程序, 就不必过问网络细节, 如: TCP, Socket等.
任意两台计算机之间的通讯完全由RMI负责, 调用远程计算机上的对象就像调用本地对象一样方便.
四、实例篇
我们编写这样一个小程序: 客户端传递两个数字给服务器端加法运算方法, 返回结果给客户端.
1. 定义一个远程接口类
/**
* 定义一个远程接口
* @author zhangjim
*/
public interface ISumService extends Remote { // 必须继承Remote接口
// 需要远程调用的方法必须抛出RemoteException
public int sum(int a, int b) throws RemoteException;
}
远程接口必须要继承: java.rmi.Remote, 接口中的每一个方法必须抛出远程异常: java.rmi.RemoteException
为什么要抛出这个异常呢? 因为任何远程方法调用实际上要进行许多低级网络操作, 而网络错误可能在调用过程中随时发生.
因此, 所有RMI操作都应该放到try-catch块中.
2. 定义一个实现远程接口的类
/**
* 远程接口的实现类
* @author zhangjim
*/
public class SumServiceImpl extends UnicastRemoteObject implements ISumService { // 必须从UnicastRemoteObject继承
private static final long serialVersionUID = -3559316404683903070L;
// 需要一个抛出Remote异常的默认初始化方法
SumServiceImpl() throws RemoteException {
}
// 业务方法, 传入两个数字, 返回相加结果
public int sum(int a, int b) throws RemoteException {
return a + b;
}
}
UnicastRemoteObject: 让客户机与服务器对象实例建立一对一的连接
3. 创建服务器, 用于启动RMI服务并绑定远程对象
public class Server {
public static void main(String[] args) {
try {
// 创建一个远程对象
ISumService sumService = new SumServiceImpl();
// 创建RMI注册表, 启动RMI服务, 并指定端口为8888(Java默认端口是1099)
// 这一步必不可少, 缺少注册表创建,则无法绑定对象到远程注册表上
LocateRegistry.createRegistry(8888);
// 把远程对象注册到RMI注册服务器上,并命名为sum
// 绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略, 下面两种写法都是正确的)
Naming.bind("rmi://localhost:8888/sum", sumService);
// Naming.bind("//localhost:8888/sum", sumService);
System.out.println("远程对象绑定成功!");
} catch (Exception e) {
throw new RuntimeException("出错了...", e);
}
}
}
也可以在命令行通过命令 rmiregistry 启动注册服务, 而且要事先用RMIC在bin目录编译SumServiceImpl类生成一个占位程序(stub类)为它所用
4. 创建客户端程序, 对RMI进行调用
/**
* 客户端测试,在客户端调用远程对象上的远程方法,并返回结果
* @author zhangjim
*/
public class Client {
public static void main(String[] args) {
try {
// 在RMI服务注册表中查找名称为sum的对象
ISumService sumService = (ISumService) Naming.lookup("rmi://localhost:8888/sum");
// 调用相加方法
System.out.println("相加结果为: " + sumService.sum(1, 2));
} catch (Exception e) {
throw new RuntimeException("出错了...", e);
}
}
}
5. 源码下载地址: http://download.csdn.net/detail/zdp072/7423041
五、RMI的文章
1. 理解RMI工作原理
2. Java RMI服务器框架