- 浏览: 11314 次
- 性别:
- 来自: 北京
最新评论
一.客户与服务器角色
在传统的客户/服务器模式中,客户请求服务器。服务器解析传输的请求,并得到响应,再传给客户端。但是这样必须考虑中间传输格式的解析。如果客户端无须关心请求的传输和解析,只调用本地方法的形式得到结果,但是有时提供服务的对象不再同一个虚拟机内,甚至不是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,然后通过网络传送到另外一个虚拟机,当你将对象传递到本地方法的是,传递的只是引用。
所以远程对象通过存根传递的,非远程对象通过复制传递。
无论何时,当调用远程方法的时候,存根将所有参数值的副本打包,发给服务器,其中用到了对象序列化机制编组参数。
发表评论
-
QQ2010山寨版--可聊天
2011-02-28 17:08 670QQ山寨比较多,前段时间密码被盗了,用了几年的QQ,密码被盗, ... -
jaf 简介
2010-11-10 15:30 0JavaBeans激活框架(JavaBeans Activ ... -
request的小问题
2010-04-15 15:46 896有段时间弄一个聊天程序: 想得到IP使用request.ge ... -
Java安全机制
2010-04-14 17:56 1322Java安全 java通过以下技术来实现安全机制 语言设 ... -
Swing基础知识学习
2010-04-14 16:09 2543高级Swing学习 一.列表 1.1 JList构件 J ... -
线程知识复习
2010-04-13 11:11 1186一.线程的实现方式 1.继承Thread 2.实现Runn ...
相关推荐
JAVA远程调用RMI与应用 一、RMI(Remote Method Invocation)概念解析 RMI,即远程方法调用,是Java平台提供的分布式计算模型,它允许Java对象跨网络进行方法调用,如同本地调用一样。RMI的实现基于Java的面向对象...
在Windows环境下,同样需要JRE,运行客户端程序来执行远程调用。 注意,RMI的安全性、异常处理和网络通信细节也是开发者需要考虑的问题。例如,需要处理可能的`RemoteException`,以及配置JVM的安全策略文件以允许...
远程调用代码RMI技术,可是实现远程方法调用的代码
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同网络节点上的Java对象之间进行通信的技术。这个技术允许一个Java对象在一台机器上执行方法,而这个方法的实现实际上位于另一台...
Java远程调用(Remote Method Invocation,RMI)是Java平台中一种重要的分布式计算技术,它允许在不同网络环境中的Java对象之间进行透明的交互。在本文中,我们将深入探讨三种不同的RMI实现方法:原始方式、Spring...
Java 远程方法调用(Remote Method Invocation,RMI)是一种在分布式环境中调用对象方法的技术,它使得Java应用程序能够透明地调用运行在不同 JVM 上的远程对象的方法。RMI 包含了一系列的参数,这些参数对于优化...
4. ** stubs 和 skeletons**:在RMI中,远程对象的引用在客户端是通过stubs(桩)表示的,而实际的远程调用则由serverside的skeleton(骨架)处理。现代的JVM已经不再需要手动生成stubs和skeletons,它们由Java...
在这个“使用rmi进行远程调用”的示例中,我们看到的是一个基于RMI实现的银行系统。这个小例子旨在帮助开发者理解如何使用RMI来构建分布式应用程序,尤其是在处理跨网络的远程对象交互时。 首先,RMI的核心概念是...
### RMI远程调用代码及使用方法 #### 一、RMI简介 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算技术,它允许开发人员在不同的Java虚拟机(JVM)之间进行对象的远程调用。通过...
Java RMI 提供了一种透明的远程调用方式,使得开发者可以像操作本地对象一样操作远程对象。 在Java RMI应用开发中,有几个关键点需要注意: 1. **远程服务接口定义**: - 接口是RMI的核心,它定义了可供远程调用...
1. 远程调用RMI(Remote Method Invocation): 通过使用 RmiProxyFactoryBean 和 RmiServiceExporter,并且,Spring支持两个传统的RMI(使用 java.rmi.Remote接口和java.rmi.RemoteException)和通过RMI调用器实现的...
**RMI远程调用详解** 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种机制,它允许一个Java对象调用另一个在不同Java虚拟机(JVM)上的对象的方法。RMI是Java分布式计算的核心技术,主要...
1. **创建远程接口**:定义一个继承自Remote的接口,声明需要远程调用的方法。 2. **实现远程接口**:编写一个类实现这个接口,提供具体的方法实现。 3. **注册远程对象**:在服务器端创建远程对象实例,然后将其...
1. **远程接口**:定义了可以被远程调用的方法,这个接口需要继承自`java.rmi.Remote`。 2. **远程实现**:实现了远程接口的具体逻辑,它通常包含实际业务功能的代码。 3. **Stub**:客户端调用的代理对象,它负责将...
接下来,`getMemberAccountCount`方法实现了远程调用逻辑,通过`this.ref.invoke`方法调用了远程方法,并处理了可能抛出的异常。 #### 2. 客户端代码分析 客户端通过`Naming.lookup`方法获取远程服务的引用,然后...
RMI采用JRMP(Java Remote Method Protocol)通讯协议,是构建在TCP/IP协议上的一种远程调用方法。它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象方法,从而使编程人员可以方便地在网络环境...
java jdk1.8; eclipse 开发环境;实现A机器的程序,可以管理(增加、删除、改等)B机器上的某个文件夹或者目录;掌握远程过程调用原理,基于...客户端利用RMI实现远程调用服务。同时,在在两台机器之间验证结果正确。
最近在学习代理模式,用到了java rmi远程调用,包含服务端和客户端,之前一直没有接触过,学习了java rmi远程调用,一方面可以了解代理模式,一方面熟悉java低层的远程
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间透明地调用对象的方法。在RMI架构中,客户端能够像调用本地对象一样调用远程服务器上的对象...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些方法是在本地对象上执行一样。这个技术极大地简化了构建分布式应用的...