RMI(Remote method invoke)远程方法调用
功能
RMI使客户对象能调用远程服务器上的方法,就像调用本地方法一样
原理
客户对象实际上是通过客户辅助对象(客户代理)和服务辅助对象(服务代理)来调用服务器上提供的服务
- 1、客户对象想要调用服务器上的方法,使用客户辅助对象(客户以为客服辅助对象就是提供服务的对象)
- 2、客户辅助对象打包调用信息(变量、方法名等),通过网络将打包信息运输给服务辅助对象,告诉服务器“客户想要调用一个方法”
- 3、服务辅助对象接收来自客户辅助对象(通过socket连接)的信息,并将其解包,根据信息调用服务对象(这才是真正的服务对象)
- 4、服务对象上的方法被调用,将得到的结果返回给服务辅助对象
- 5、服务辅助对象将返回信息打包,通过网络传给客户辅助对象
- 6、客户辅助对象解包返回信息,返回给客户对象
上述过程,对于客户来说透明的(看上去像没有,实际存在),即不可见
使用RMI的例子
远程接口——客户端通过访问该对象来调用服务端的方法,服务端需要实现该接口
import java.rmi.*;
/**
* 制作远程接口
*/
public interface MyRemote extends Remote {
public String sayHello() throws RemoteException;
}
服务实现
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* 制作远程实现
* 需要继承UnicastRemoteObject,来完成远程功能
*/
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
protected MyRemoteImpl() throws RemoteException {
//由于父类UnicastRemoteObject的构造函数抛出了异常,所以子类申明自己的构造函数并抛出异常
}
@Override
public String sayHello() throws RemoteException {
return "Server say - hello";
}
public static void main(String[] args) {
try {
//产生远程对象
MyRemote service = new MyRemoteImpl();
//绑定到rmiregistry,客户讲在注册的rmiregistry中找相应名字的远程对象
//rmiregistry相当于一个通讯录
Naming.rebind("RemoteHello", service);
System.out.println("the server is ready");
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户调用服务的方法
import java.rmi.*;
public class MyRemoteClient {
public static void main(String[] args) {
new MyRemoteClient().go();
}
public void go() {
try {
//在rmiregistry中查找已注册的服务
MyRemote service = (MyRemote) Naming.lookup("rmi://localhost/RemoteHello");
String s = service.sayHello();
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果
在运行的时候需要先启动rmiregistry,Naming.rebind()注册服务的时候rmiregistry必须运行
在cmd中进入所在项目的bin目录下运行start rmiregistry,弹出一个黑框
运行服务代码:
运行客户代码:
细节
1、可在eclipse里面加载rmi的插件运行。
2、在RMI中客户辅助对象为Stub,服务辅助对象为Skeleton
早期还需要运行rmic产生Stub和Skeleton,但是现在新一点的版本JVM会自动生成,不需要我们再手动运行,但是是存在的。可以通过rmi插件查看其文件
RMI原理图(时序图)
http://haolloyin.blog.51cto.com/1177454/332426
demo视频(安装和例子)
http://www.genady.net/rmi/v20/demos/
java RMI 在eclipse中的实现
http://blog.youkuaiyun.com/sima1989/article/details/41045249