首页 > 代码库 > RMI

RMI

RMI(远程接口调用) 
1. RMI的原理: 
RMI系统结构,在客户端和服务器端都有几层结构。 

方法调用从客户对象经占位程序(Stub)、远程引用层(Remote Reference Layer)和传输层(Transport Layer)向下,传递给主机,然后再次经传 输层,向上穿过远程调用层和骨干网(Skeleton),到达服务器对象。 占位程序扮演着远程服务器对象的代理的角色,使该对象可被客户激活。 远程引用层处理语义、管理单一或多重对象的通信,决定调用是应发往一个服务器还是多个。传输层管理实际的连接,并且追追踪可以接受方法调用的远程对象。服务器端的骨干网完成对服务器对象实际的方法调用,并获取返回值。返回值向下经远程引用层、服务器端的传输层传递回客户端,再向上经传输层和远程调用层返回。最后,占位程序获得返回值。 

2. RMI(远程方法调用)的组成 
一个正常工作的RMI系统由下面几个部分组成: 

  ?远程服务的接口定义 
  ?远程服务接口的具体实现 
  ?桩(Stub)和框架(Skeleton)文件 
  ?一个运行远程服务的服务器 
  ?一个RMI命名服务,它允许客户端去发现这个远程服务 
  ?类文件的提供者(一个HTTP或者FTP服务器) 
      ?一个需要这个远程服务的客户端程序 

技术原理

RMI系统结构,在客户端和服务器端都有几层结构。

--------- ----------

| 客户 | |服务器|

---------- ----------

| |

------------- ----------

| 占位程序| |骨干网|

-------------- -----------

| |

------------------------------------

| 远 程 引 用 层 |

------------------------------------

| |

------------------------------------

| 传 输 层 |

------------------------------------

方法调用从客户对象经占位程序(Stub)、远程引用层(Remote Reference Layer)和传输层(Transport Layer)向下,传递给主机,然后再次经传 输层,向上穿过远程调用层和骨干网(Skeleton),到达服务器对象。 占位程序扮演着远程服务器对象的代理的角色,使该对象可被客户激活。 远程引用层处理语义、管理单一或多重对象的通信,决定调用是应发往一个服务器还是多个。传输层管理实际的连接,并且追追踪可以接受方法调用的远程对象。服务器端的骨干网完成对服务器对象实际的方法调用,并获取返回值。返回值向下经远程引用层、服务器端的传输层传递回客户端,再向上经传输层和远程调用层返回。最后,占位程序获得返回值。

要完成以上步骤需要有以下几个步骤:

1、生成一个远程接口

2、实现远程对象(服务器端程序)

3、生成占位程序和骨干网(服务器端程序)

4、编写服务器程序

5、编写客户程序

6、注册远程对象

7、启动远程对象

一、远程接口:

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Ihello  extends Remote{
 
   public String sayHello(String name) throws RemoteException ;
   
   public String hello() throws RemoteException;
}

    实现类:

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.wa.spring.rmi.dao.Ihello;
public class HelloImpl extends UnicastRemoteObject implements Ihello {
 public HelloImpl() throws RemoteException {
  super();
 }
 public String sayHello(String name) throws RemoteException {
  return "hello, welcome "+name;
 }
 public String hello() throws RemoteException {
  return "good rmi";
 }
}

  方法要抛出RemoteException否则出现以下异常:

 

 

二、实现远程对象创建服务端程序:

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import com.wa.spring.rmi.dao.Ihello;
import com.wa.spring.rmi.dao.impl.HelloImpl;

/**
 * 
 * @author Administrator
 * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。 
 */
public class HelloServer {
 
 public static void main(String[] args) {
   
  try {
    //创建一个远程对象 
   Ihello hello = new HelloImpl();
   //  //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,
   //这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上
   LocateRegistry.createRegistry(8888);
    //把远程对象注册到RMI注册服务器上,并命名为Hello 
            //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的) 
   
       Naming.bind("rmi://localhost:8888/Hello",hello); 
//           Naming.bind("//localhost:8888/RHello",rhello); 
       
       System.out.println("====>>>url绑定成功");
  } catch (RemoteException e) {
    System.out.println("创建远程对象发生异常!"); 
   e.printStackTrace();
  } catch (MalformedURLException e) {
   System.out.println("url异常");
   e.printStackTrace();
  } catch (AlreadyBoundException e) {
   System.out.println("重复绑定异常");
   e.printStackTrace();
  }
 }
}

三、创建客户端程序:

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import com.wa.spring.rmi.dao.Ihello;
/**
 * 在客户端调用远程对象上的远程方法,并返回结果。 
 * @author Administrator
 *
 */
public class HelloClient {
 
 public static void main(String[] args) {
  
    try {
     //调用注册的服务
   Ihello hello = (Ihello) Naming.lookup("rmi://localhost:8888/Hello");
   System.out.println(hello.hello());
   System.out.println(hello.sayHello("纳兰容若"));
  } catch (MalformedURLException e) {
   e.printStackTrace();
  } catch (RemoteException e) {
   e.printStackTrace();
  } catch (NotBoundException e) {
   e.printStackTrace();
  }
 }
}

分别运行服务端和客户端可看到输出信息!

 

参考资料:

http://baike.baidu.com/view/99017.htm?fr=aladdin

http://www.ibm.com/developerworks/cn/java/j-rmiframe/

RMI