RMI(Remote method invoke)详解

来源:互联网 发布:淘宝有名片设计吗 编辑:程序博客网 时间:2024/05/28 08:29

  • RMIRemote method invoke远程方法调用
    • 功能
    • 原理
    • 使用RMI的例子
    • 细节

RMI(Remote method invoke)远程方法调用

功能

RMI使客户对象能调用远程服务器上的方法,就像调用本地方法一样

原理

客户对象实际上是通过客户辅助对象(客户代理)和服务辅助对象(服务代理)来调用服务器上提供的服务
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.csdn.net/sima1989/article/details/41045249