远程方法调用(Remote Method Invocation,RMI)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
一个正常工作的RMI系统由下面几个部分组成:·
.远程服务的接口定义
·远程服务接口的具体实现
·桩(Stub)和框架(Skeleton)文件
·一个运行远程服务的服务器
·一个RMI命名服务,它允许客户端去发现这个远程服务
·类文件的提供者(一个HTTP或者FTP服务器)
·一个需要这个远程服务的客户端程序
要完成以上步骤需要有以下几个步骤:
1、生成一个远程接口
2、实现远程对象(服务器端程序)
3、生成占位程序和骨干网(服务器端程序)
4、编写服务器程序
5、编写客户程序
6、注册远程对象
7、启动远程对象
package com.weiythi.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ITimeService extends Remote{
public long getTime() throws RemoteException;
}
2. 实现远程接口及远程方法(继承UnicastRemoteObject)TimerService.java
package com.weiythi.service;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class TimerService extends UnicastRemoteObject implements ITimeService{
private static final long serialVersionUID = 1L;
/**
* 必须定义构造方法,即使是默认构造方法,也必须把它明确地写出来,因为它必须抛出出RemoteException异常
*/
public TimerService() throws RemoteException{
}
/**
* 接口方法的实现
*/
@Override
public long getTime() throws RemoteException {
return System.currentTimeMillis();
}
}
3. 启动RMI注册服务,并注册远程对象
方法一,打开一个DOS窗口,使用rmic命令
rmic com.weiythi.service.TimerService
启动RMI注册服务,指定端口为1099 (1099为默认端口)
start rmiregistry
注册远程对象(StartTimerServer.java)
package com.weiythi.service;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class StartTimerServer {
public static void main(String[] args){
try {
TimerService timerservice=new TimerService();
//把TimerService注册到RMI注册服务器上,命名为b1
Naming.bind("b1", timerservice);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AlreadyBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
方法二:
package com.weiythi.service;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class StartTimerServer {
public static void main(String[] args){
try {
//启动RMI注册服务
//也可以通过命令 start rmigesitry启动
//这里用这种方式避免了再打开一个DOS窗口
//而且用命令rmiregistry启动注册服务还必须事先用RMIC生成一个stub类为它所用
LocateRegistry.createRegistry(1099);
TimerService timerservice=new TimerService();
//把TimerService注册到RMI注册服务器上,命名为b1
Naming.bind("b1", timerservice);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AlreadyBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4. 客户端查找远程对象,并调用远程方法(GetTimerService.java)
package com.weiythi.client;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import com.weiythi.service.ITimeService;
public class GetTimerService {
public static void main(String[] args){
try {
ITimeService time=(ITimeService) Naming.lookup("rmi://localhost/b1");
System.out.println("the time is:"+time.getTime());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}