java RMI远程方法调用详解

1.RMI 目前使用Java远程消息交 换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的“Write Once,Run Anywhere”的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(JavaRun Environment Java,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。

2.一个正常工作的RMI系统由下面几个部分组成:

 1)远程服务的接口定义,该接口必须实现Remote接口,Remote接口仅仅是一个没有方法的标记型接口;
 2)远程服务接口的具体实现,写一个实现类继承UnicastRemoteObject类然后实现自己定义的那个远程接口;
 3)桩(Stub)和框架(Skeleton)文件,stub是远程对象的客户端代理,通过它可以实现远程方法的调用,而skeleton是服务器端的骨架,将stub的调用具体分配给实际的远程对象实现;
 4)一个运行远程服务的服务器
 5)一个RMI命名服务,它允许客户端去发现这个远程服务
 6)类文件的提供者(一个HTTP或者FTP服务器)
 7)一个需要这个远程服务的客户端程序

3.具体实现的四个步骤:
1. 
创建远程接口及声明远程方法(HelloInterface.java
2. 
实现远程接口及远程方法(继承UnicastRemoteObject(Hello.java)
3. 
启动RMI注册服务,并注册远程对象(HelloServer.java
4. 
客户端查找远程对象,并调用远程方法(HelloClient
5. 
执行程序:启动服务HelloServer;运行客户端HelloClient进行调用


4.代码实现:

1) 创建远程接口及声明远程方法(HelloInterface.java

java 代码

packagecom.unmi;   

 import java.rmi.*;

 /** 

  * 远程接口必须扩展接口java.rmi.Remote 

  */ 

 public interface HelloInterface extends Remote  {  

    /** 

    * 远程接口方法必须抛出java.rmi.RemoteException 

    */ 

    public String say() throws RemoteException;  

 }   

2) 实现远程接口及远程方法(继承UnicastRemoteObjectHello.java

如果传递参数,参数必须是可序列化的参数实现java.io.Serializable

java 代码

packagecom.unmi;  

importjava.rmi.*;  

importjava.rmi.server.*;  

/**

 * 扩展了UnicastRemoteObject类,并实现远程接口 HelloInterface

 */ 

publicclass Hello extends UnicastRemoteObject implements HelloInterface  {  

   private Stringmessage;  

   /**

    * 必须定义构造方法,即使是默认构造方法,也必须把它明确地写出来,因为它必须抛出出RemoteException异常

    */ 

   public Hello(Stringmsg) throws RemoteException

   {  

     message = msg;  

   }  

   /**

    * 远程接口方法的实现

    */ 

   public String say() throws RemoteException  

   {  

      System.out.println("Called by HelloClient");  

      returnmessage;  

   }  

 

3) 启动RMI注册服务,并注册远程对象(HelloServer.java

java 代码

packagecom.unmi;

importjava.rmi.Naming;  

importjava.rmi.registry.LocateRegistry;  

publicclass HelloServer  {  

   /**

    * 启动 RMI 注册服务并进行对象注册

    */ 

   public static void main(String[]argv)  

   {  

      try 

      {  

         //启动RMI注册服务,指定端口为1099 (1099为默认端口) 

         //也可以通过命令 java_home/bin/rmiregistry1099启动 

         //这里用这种方式避免了再打开一个DOS窗口 

         //而且用命令rmiregistry启动注册服务还必须事先用RMIC生成一个stub类为它所用 

        LocateRegistry.createRegistry(1099); 

         //创建远程对象的一个或多个实例,下面是hello对象 

         //可以用不同名字注册不同的实例 

         HelloInterface hello = new Hello("Hello,world!");   

         //hello注册到RMI注册服务器上,命名为Hello 

         Naming.rebind("Hello",hello);

         //如果要把hello实例注册到另一台启动了RMI注册服务的机器上 

         //Naming.rebind("//192.168.1.105:1099/Hello",hello);

         System.out.println("Hello Server is ready.");  

      }  

      catch(Exception e)   

      {  

         System.out.println("Hello Server failed: " + e);  

      }  

   }  

4) 客户端查找远程对象,并调用远程方法(HelloClient

java 代码

packagecom.unmi;  

importjava.rmi.Naming;  

publicclass HelloClient  {  

   /**

    * 查找远程对象并调用远程方法

    */  

   public static void main(String[]argv){  

      try{  

    HelloInterface hello = (HelloInterface)Naming.lookup("Hello");  

         //如果要从另一台启动了RMI注册服务的机器上查找hello实例 

         //HelloInterfacehello = (HelloInterface)Naming.lookup("//192.168.1.105:1099/Hello"); 

        //调用远程方法 

         System.out.println(hello.say());  

      }  

      catch(Exception e)  

      {  

         System.out.println("HelloClient exception: " + e);  

      }  

   }  

  

5)执行程序:启动服务HelloServer;运行客户端HelloClient进行调用
代码如何编译这里就不细讲
(1)
打开一个Dos窗口执行命令 java com.unmi.HelloServer 启动服务HelloServer
E:workspaceTestRMIbin>java com.unmi.HelloServer
Hello Server is ready.
运行成功则可以看到Hello Server is ready
(2)
打开另一个Dos窗口执行命令 java com.unmi.HelloClient 运行客户端程序
E:workspaceTestRMIbin>java com.unmi.HelloClient
Hello, world!
调用成功则可以看到 Hello,world!
并且在启动服务端的窗口中看到紧跟 Hello Server is ready. 打印出
Called by HelloClient
6)到这里就全部完成,测试使用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值