java 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、启动远程对象

一、远程接口:

  

package com.wa.spring.rmi.dao;

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;

}

二、实现类:

package com.wa.spring.rmi.dao.impl;

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否则出现以下异常:

  

 

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

package com.wa.spring.rmi;

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();
        }
    }

}

三、创建客户端程序:

package com.wa.spring.rmi;

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/

posted @ 2015-02-01 09:18  snow__wolf  阅读(186)  评论(0)    收藏  举报