RMI 过程方法调用
能够让在某个Java虚拟机上的对象像调用本地对象一样调用另一个java 虚拟机中的对象上的方法。
RPC 远程过程调用
用于一个进程调用另一个进程(很可能在另一个远程主机上)中的过程,从而提供了过程的分布能力。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,即提供分布式对象间的通讯。
RMI 服务注册步骤
1. 实现接口或者继承相关类
Remote 接口
表明接口允许被远程访问
UniCastRemoteObject 类
表示该具体服务对象可以被输出到客户端,供客户端调用
实现以上接口或者类的对象才能用作RMI对象
代码示例:
接口 Fly
public interface Fly extends Remote{
String fly(String words) throws RemoteException;
}
接口实现 HelloFly
public class HelloFly extends UnicastRemoteObject implements Fly{
private static final long serialVersionUID = 1L;
protected HelloFly() throws RemoteException {
super();
}
@Override
public String fly(String words) throws RemoteException {
System.out.println("hello fly " + words + "in server service");
return "hello fly" + words;
}
}
服务端注册服务代码
public class RMIServer {
public static void main(String[] args) throws RemoteException{
try {
LocateRegistry.createRegistry(1099);
Fly fly = new HelloFly();
Naming.bind("rmi://localhost/fly01", fly);
System.out.println("HelloServer start success");
} catch (MalformedURLException | AlreadyBoundException e) {
e.printStackTrace();
System.out.println("bind service fail.");
}
}
}
客户端获取服务,进行调用代码
public class RMIClient {
public static void main(String[] args) {
Fly fly;
try {
fly = (Fly)Naming.lookup("rmi://localhost/fly01");
System.out.println(fly.fly("good jobs"));
} catch (MalformedURLException | RemoteException | NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
RMI远程调用步骤
Client<–>stub<–>[socket NETWORK]<–>skeleton<–>Server
在jdk1.2之后,skeleton就被合并到server中了
Client<—>stub<—>[NETWORK]<—>Server_with_skeleton
RMI远程调用步骤:
1. 客户对象调用客户端辅助对象stub上的方法
2. 客户端辅助对象打包调用信息(变量,方法名),通过网络发送给服务端辅助对象
3. 服务端辅助对象skeleton将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
4. 调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象
5. 服务端辅助对象将结果打包,发送给客户端辅助对象
6. 客户端辅助对象将返回值解包,返回给客户对象
7. 客户对象获得返回值
客户端获取服务器端远程对象的拷贝 存根 stub
服务端本身存在的远程对象 骨架 skeleton
以上两者都可以称为远程对象的代理。
RMIRegistry 远程服务对象的注册中心
启动
LocateRegistry.createRegistry(1099);
作用:
1. 服务端,将远程对象注册到注册中心中
2. 客户端,通过url得到远程对象在本地的代理,即stub.
使用手动命令行实现 java rmi
使用rmic xxx.class 生成xxx_stub.class文件,该存根文件是远程对象在本地的代理,通过服务端代码xxx.java生成(现在已经过时)
打开注册机服务。java_home/bin/rmiregistry
运行服务端绑定远程服务程序
Fly fly = new HelloFly();
Naming.bind("rmi://localhost/fly01", fly);
客户端使用远程服务
fly = (Fly)Naming.lookup("rmi://localhost/fly01");
System.out.println(fly.fly("good jobs"));
如果出现连接拒绝,可能是因为rmiregistry或者运行服务端程序被终止了。
参考博文,感谢前辈分享
http://haolloyin.blog.51cto.com/1177454/332426/
http://blog.csdn.net/a19881029/article/details/9465663
http://blog.csdn.net/xinghun_4/article/details/45787549
http://www.jianshu.com/p/2c78554a3f36