`
yelangchs
  • 浏览: 11312 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

远程调用RMI

    博客分类:
  • Java
阅读更多

一.客户与服务器角色

在传统的客户/服务器模式中,客户请求服务器。服务器解析传输的请求,并得到响应,再传给客户端。但是这样必须考虑中间传输格式的解析。如果客户端无须关心请求的传输和解析,只调用本地方法的形式得到结果,但是有时提供服务的对象不再同一个虚拟机内,甚至不是java虚拟机,那怎么办,解决的办法是在客户端提供一个服务器的代理,客户直接调用这个代理,这个代理负责客户与服务器交流。同样,在服务器也安装一个代理负责服务器与客户端通信。并以常规方式调用服务器方法。接下来的问题就是代理之间是怎么通信的呢。

RMI----------------Java远程方法调用技术,支持java的分布式对象之间的调用

CORBA------------通用对象请求架构,支持任何编程语言编写的对象之间的方法调用,CORBA使用Internet inter-ORB协议(IIOP)支持对象间的通信

SOAP--------------简单对象访问协议,它也独立编程语言。基于XML的传输格式。

另外,MicroSoft也使用另一种底层协议COM支持对象间通信。

CORBA和SOAP都是独立于语言的,客户端和服务器完全使用C,C++,Java来编写,只要你提供一种接口描述,以说明你的对象能够处理的方法的签名和数据类型。该接口描述是一种特殊的描述语言,对于CORBA来说接口定义语言是(IDL),对于SOAP则是Web服务描述语言(WSDL)。

CORBA更加高效,而SOAP更适合Web架构的系统。如果通信的对象都是Java实现的,那么最好使用RMI。

 

二.远程方法调用

客户端对象------------------一般是发起远程调用的对象

服务器对象------------------相应的远程对象

2.1 存根和参数编组

存根-------------当客户端代码调用一个远程方法时,实际上是调用的一个本地方法,我们称此代理对象为存根,存根位于客户端上,而不是服务器上,存根将调用远程方法所需的参数打包成一组字节,这个打包过程是与硬件无关的编码的编码方式进行编码。

参数编组--------对参数编码的过程叫参数编组,它的目的是将参数转换成适合在虚拟机传输的格式。

总之,客户端的存根构造一个信息块,它由以下几部分组成:

  • 被使用的远程对象的标示符
  • 被调用的方法的描述
  • 编组后的参数

然后将这个信息块发送到服务器,服务器接受对象为每个远程方法执行以下动作

  • 反编组参数
  • 定位要调用的对象
  • 调用所需的方法
  • 捕获返回值或者调用产生的异常,对它进行编组;
  • 对返回值编组,打包送回客户端存根

客户端存根对接受到得返回值编组进行反编组,如果远程方法抛出异常,客户端存根在客户端处理空间中重新抛出异常。

2.2 动态类加载

当一个远程对象,作为远程方法的参数或者返回值,传递给另一个程序时,该程序很显然需要这个对象的Class文件。

 

三.配置远程方法调用

首先,你必须在客户端和服务器同时运行程序,其次,必要的对象信息被划分为客户端接口和服务器实现。还有专门的查询机制,能够使得客户端准确定位服务器上的对象

3.1 接口与实现

客户端可能需要操纵服务器对象,但是实际上它并不需要真正的服务器对象的引用,因为它只要知道这个对象时干什么的就可以了,我们可以使用接口的方式来描述它能做什么。而这些接口是客户端和服务器共享的,它必须同时存在于客户端和服务器。注意的是远程对象的接口必须继承与Remote。而且必须抛出RemoteException异常。

package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Product extends Remote {
	String getDescription() throws RemoteException;
}

 

然后呢,在服务器必须实现这个接口

服务器类通常继承RemoteServer。

package rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ProductImpl extends UnicastRemoteObject implements Product {

	private String desc;
	
	public ProductImpl(String desc) throws RemoteException {
		super();
		this.desc = desc;
	}

	@Override
	public String getDescription() throws RemoteException {
		// TODO Auto-generated method stub
		return "I am a "+desc+"buy me!";
	}

}

 

3.2 存根类生成

从JDK5.0开始,存根类可以自动生成,但是在这之前,存根类必须手动生成:

rmic -v1.2 ProductImpl

它会生成两个文件ProductImpl_Stub.class和ProductImpl_Skel.class

3.3 定位服务器对象

要访问服务器的远程对象,必须获得一个客户端存根,最直接的方法时调用远程方法,获得返回值返回存根,但是这样第一个远程对象怎么获得呢。RMI类库提供了自举注册服务来定位第一个服务器对象。通过给自举注册服务提供一份对象的引用和名字,就可以注册服务器对象,客户端就可以获得对象的存根。这些对象的名称最好唯一。

 

package rmi;

import java.rmi.RemoteException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class ProductServer {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			System.out.println("Constructing server implementations...");

			ProductImpl p1=new ProductImpl("boy");
			
			ProductImpl p2=new ProductImpl("girl");
			
			System.out.println("Binding server implementations to registry...");
			Context namingContext = new InitialContext();
			
			namingContext.bind("rmi:b",p1);
			namingContext.bind("rmi:g",p2);
			
			System.out.println("Waiting for invocation from clients....");
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

1.启动服务器(windows)

start rmiregistry

start java ProductServer

2.列举远程对象

NamingEnumeration<NameClassPair> e = namingContext.list("rmi:");

package rmi2.ShowBindings;


/**
   @version 1.10 2004-08-14
   @author Cay Horstmann
*/

import java.rmi.*;
import java.rmi.server.*;
import javax.naming.*;

/**
   This programs shows all RMI bindings.
*/
public class ShowBindings
{  
   public static void main(String[] args)
   {  
      try
      {  
         Context namingContext = new InitialContext();
         NamingEnumeration<NameClassPair> e = namingContext.list("rmi:");
         while (e.hasMore())
            System.out.println(e.next().getName());
      }
      catch (Exception e)
      {  
         e.printStackTrace();
      }
   }
}

 

3.4 编写客户端代码

使用RMI的客户端必须安装一个安全管理器,用以动态加载存根的行为。

System.setSecurityManager(new RMIsetSecurityManager)

package rmi2.Product;

/**
   @version 1.20 2004-08-15
   @author Cay Horstmann
*/

import java.rmi.*;
import java.rmi.server.*;
import javax.naming.*;

/**
   This program demonstrates how to call a remote method
   on two objects that are located through the naming service.
*/
public class ProductClient
{  
   public static void main(String[] args)
   {  
      System.setProperty("java.security.policy", "client.policy");
      System.setSecurityManager(new RMISecurityManager());
      String url = "rmi://localhost/";
         // change to "rmi://yourserver.com/" when server runs on remote machine yourserver.com
      try
      {  
         Context namingContext = new InitialContext();
         Product c1 = (Product) namingContext.lookup(url + "toaster");
         Product c2 = (Product) namingContext.lookup(url + "microwave");         

         System.out.println(c1.getDescription());
         System.out.println(c2.getDescription());
      }
      catch (Exception e)
      {  
         e.printStackTrace();
      }
   }
}

 

要允许客户端连接RMI注册表以及服务器对象,必须提供一个策略文件。服务器对象使用的是大于1024的端口,RMI默认端口是1099.

client.policy

grant 
{  
   permission java.net.SocketPermission 
      "*:1024-65535", "connect,accept";
   permission java.net.SocketPermission 
      "localhost:80", "connect";
};

 总之。

  • 编译接口,实现类,服务器类,客户端类等文件
  • 启动RMI注册表     start rmiregistry

 对于RMI的部署相当的麻烦,一般初学者很容易出错,我也没有深入研究学习,在这里我也不说了。有兴趣的人可以上Google搜索。

 

四.远程方法的参数传递

4.1 传递非远程对象

  当一个不是远程对象的对象,需要从一个java虚拟机传送另外一个java虚拟机时,第一个java虚拟机会制作一个对象COPY,然后通过网络传送到另外一个虚拟机,当你将对象传递到本地方法的是,传递的只是引用。

所以远程对象通过存根传递的,非远程对象通过复制传递。

无论何时,当调用远程方法的时候,存根将所有参数值的副本打包,发给服务器,其中用到了对象序列化机制编组参数。

 

分享到:
评论

相关推荐

    JAVA远程调用RMI与应用

    JAVA远程调用RMI与应用 一、RMI(Remote Method Invocation)概念解析 RMI,即远程方法调用,是Java平台提供的分布式计算模型,它允许Java对象跨网络进行方法调用,如同本地调用一样。RMI的实现基于Java的面向对象...

    java远程调用rmi实例

    在Windows环境下,同样需要JRE,运行客户端程序来执行远程调用。 注意,RMI的安全性、异常处理和网络通信细节也是开发者需要考虑的问题。例如,需要处理可能的`RemoteException`,以及配置JVM的安全策略文件以允许...

    远程调用RMI代码

    远程调用代码RMI技术,可是实现远程方法调用的代码

    java 远程调用rmi实现的简单例子

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同网络节点上的Java对象之间进行通信的技术。这个技术允许一个Java对象在一台机器上执行方法,而这个方法的实现实际上位于另一台...

    三种方式实现java远程调用(rmi),绝对可用

    Java远程调用(Remote Method Invocation,RMI)是Java平台中一种重要的分布式计算技术,它允许在不同网络环境中的Java对象之间进行透明的交互。在本文中,我们将深入探讨三种不同的RMI实现方法:原始方式、Spring...

    Java-远程方法调用RMI参数详解.docx

    Java 远程方法调用(Remote Method Invocation,RMI)是一种在分布式环境中调用对象方法的技术,它使得Java应用程序能够透明地调用运行在不同 JVM 上的远程对象的方法。RMI 包含了一系列的参数,这些参数对于优化...

    RMI实现的远程调用

    4. ** stubs 和 skeletons**:在RMI中,远程对象的引用在客户端是通过stubs(桩)表示的,而实际的远程调用则由serverside的skeleton(骨架)处理。现代的JVM已经不再需要手动生成stubs和skeletons,它们由Java...

    使用rmi进行远程调用

    在这个“使用rmi进行远程调用”的示例中,我们看到的是一个基于RMI实现的银行系统。这个小例子旨在帮助开发者理解如何使用RMI来构建分布式应用程序,尤其是在处理跨网络的远程对象交互时。 首先,RMI的核心概念是...

    RMI远程调用代码及使用方法

    ### RMI远程调用代码及使用方法 #### 一、RMI简介 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算技术,它允许开发人员在不同的Java虚拟机(JVM)之间进行对象的远程调用。通过...

    java调用RMI小结

    Java RMI 提供了一种透明的远程调用方式,使得开发者可以像操作本地对象一样操作远程对象。 在Java RMI应用开发中,有几个关键点需要注意: 1. **远程服务接口定义**: - 接口是RMI的核心,它定义了可供远程调用...

    Spring 实现远程访问详解——rmi

    1. 远程调用RMI(Remote Method Invocation): 通过使用 RmiProxyFactoryBean 和 RmiServiceExporter,并且,Spring支持两个传统的RMI(使用 java.rmi.Remote接口和java.rmi.RemoteException)和通过RMI调用器实现的...

    RMI远程调用

    **RMI远程调用详解** 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种机制,它允许一个Java对象调用另一个在不同Java虚拟机(JVM)上的对象的方法。RMI是Java分布式计算的核心技术,主要...

    Java RMI(远程方法调用)Demo

    1. **创建远程接口**:定义一个继承自Remote的接口,声明需要远程调用的方法。 2. **实现远程接口**:编写一个类实现这个接口,提供具体的方法实现。 3. **注册远程对象**:在服务器端创建远程对象实例,然后将其...

    RMI远程方法调用RMI远程方法调用

    1. **远程接口**:定义了可以被远程调用的方法,这个接口需要继承自`java.rmi.Remote`。 2. **远程实现**:实现了远程接口的具体逻辑,它通常包含实际业务功能的代码。 3. **Stub**:客户端调用的代理对象,它负责将...

    JAVA RMI远程调用方法代码

    接下来,`getMemberAccountCount`方法实现了远程调用逻辑,通过`this.ref.invoke`方法调用了远程方法,并处理了可能抛出的异常。 #### 2. 客户端代码分析 客户端通过`Naming.lookup`方法获取远程服务的引用,然后...

    RMI远程过程调用

    RMI采用JRMP(Java Remote Method Protocol)通讯协议,是构建在TCP/IP协议上的一种远程调用方法。它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象方法,从而使编程人员可以方便地在网络环境...

    RMI远程过程调用(远程文件管理)

    java jdk1.8; eclipse 开发环境;实现A机器的程序,可以管理(增加、删除、改等)B机器上的某个文件夹或者目录;掌握远程过程调用原理,基于...客户端利用RMI实现远程调用服务。同时,在在两台机器之间验证结果正确。

    java rmi远程调用

    最近在学习代理模式,用到了java rmi远程调用,包含服务端和客户端,之前一直没有接触过,学习了java rmi远程调用,一方面可以了解代理模式,一方面熟悉java低层的远程

    java rmi远程方法调用 客户端

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间透明地调用对象的方法。在RMI架构中,客户端能够像调用本地对象一样调用远程服务器上的对象...

    Java RMI 远程方法调用

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些方法是在本地对象上执行一样。这个技术极大地简化了构建分布式应用的...

Global site tag (gtag.js) - Google Analytics