当前位置: 首页 > news >正文

【Java基础】- RMI原理和使用详解

【Java基础】- RMI原理和使用详解

文章目录

  • 【Java基础】- RMI原理和使用详解
    • 一、什么RMI
    • 二、RMI原理
      • 2.1 工作原理图
      • 2.2 工作原理
    • 三、RMI远程调用步骤
      • 3.1 RMI远程调用运行流程图
      • 3.2 RMI 远程调用步骤
    • 四、JAVA RMI简单实现
      • 4.1 如何实现一个RMI程序
      • 4.2 JAVA实现RMI程序

一、什么RMI

RMI:远程方法调佣(Remort Method Invocation),它支持存储于不同地址空间的程序级对象之间彼此通信,实现远程对象之间的无缝远程调用。

JAVA RMI:用于不同虚拟机之间的通信,这些虚拟机可以在不同的主机上,也可以在同一个主机上;一个虚拟机中的对象调用另一个虚拟机上中的对象的方法,只不过是允许被远程调用的对象要通过一些标志加以标识。

远程过程调用(Remote Procedure Call,RPC):可以用于一个进程调用另一个进程(很可能在另一个远程主机上)中的过程,从而提供了过程的分布能力。Java的RMI则在RPC的基础上向前又迈进了一步,既提供分布式对象间通讯。

二、RMI原理

2.1 工作原理图

在这里插入图片描述

2.2 工作原理

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

实际上,客户端只与代表远程主机中对象的Stub对象进行通信,丝毫不知道Server的存在。客户端只是调用Stub对象中的本地方法,Stub对象是一个本地对象,它实现了远程对象向外暴露的接口,也就是说它的方法和远程对象暴露的方法的签名是相同的。客户端认为它是调用远程对象的方法,实际上是调用Stub对象中方法,可以理解为Stub对象是远程对象在本地的一个代理,当客户端调用方法的时候,Stub对象会将调用通过网络传输给远程对象。

三、RMI远程调用步骤

3.1 RMI远程调用运行流程图

3.2 RMI 远程调用步骤

  1. 客户端对象调用客户端辅助对象(Stub)上的方法。
  2. 客户端辅助对象打包调用信息(变量、方法名),通过网络发送给服务端辅助对象。
  3. 服务端辅助对象将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象。
  4. 调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象。
  5. 服务端辅助对象将结果打包,发送给客户端辅助对象。
  6. 客户端辅助对象将返回值解包,返回给客户对象
  7. 客户对象获得返回值

四、JAVA RMI简单实现

4.1 如何实现一个RMI程序

1). 创建远程接口, 并且继承java.rmi.Remote接口。

2). 实现远程接口,并且继承:UnicastRemoteObject。

3). 创建服务器程序: createRegistry方法注册远程对象,暴露一个监听。

4). 创建客户端程序,通过ip和端口连接到指定的服务器,并且将数据做封装(序列化)

5). 服务器端收到请求,先反序列化。再进行业务逻辑处理。把返回结果序列化返回

4.2 JAVA实现RMI程序

1). 定义一个远程接口

/*** 必须继承Remote接口。* 所有参数和返回类型必须序列化(因为要网络传输)。* 任意远程对象都必须实现此接口。* 只有远程接口中指定的方法可以被调用。*/
public interface IRemoteMath extends Remote {// 所有方法必须抛出RemoteExceptionpublic double add(double a, double b) throws RemoteException;public double subtract(double a, double b) throws RemoteException;	
}

2). 远程接口实现类

/*** 服务器端实现远程接口。* 必须继承UnicastRemoteObject,以允许JVM创建远程的存根/代理。*/
public class RemoteMath extends UnicastRemoteObject implements IRemoteMath {private int numberOfComputations;protected RemoteMath() throws RemoteException {numberOfComputations = 0;}@Overridepublic double add(double a, double b) throws RemoteException {numberOfComputations++;System.out.println("Number of computations performed so far = " + numberOfComputations);return (a+b);}@Overridepublic double subtract(double a, double b) throws RemoteException {numberOfComputations++;System.out.println("Number of computations performed so far = " + numberOfComputations);return (a-b);}}

3). 服务器端

/* 注册远程对象,向客户端提供远程对象服务 * 远程对象是在远程服务上创建的,你无法确切地知道远程服务器上的对象的名称* 但是,将远程对象注册到RMI Service之后,客户端就可以通过RMI Service请求* 到该远程服务对象的stub了,利用stub代理就可以访问远程服务对象了*/
public class RMIServer {public static void main(String[] args)  {try {IRemoteMath remoteMath = new RemoteMath();  LocateRegistry.createRegistry(1088);    Registry registry = LocateRegistry.getRegistry();registry.bind("Compute", remoteMath);System.out.println("Math server ready");} catch (Exception e) {e.printStackTrace();}		}}

4). 客户端

public class MathClient {public static void main(String[] args) {try { // 如果RMI Registry就在本地机器上,URL就是:rmi://localhost:1088/Compute// 否则,URL就是:rmi://RMIService_IP:1088/ComputeRegistry registry = LocateRegistry.getRegistry("localhost");        // 从Registry中检索远程对象的存根/代理IRemoteMath remoteMath = (IRemoteMath)registry.lookup("Compute");// 调用远程对象的方法double addResult = remoteMath.add(5.0, 3.0);System.out.println("5.0 + 3.0 = " + addResult);double subResult = remoteMath.subtract(5.0, 3.0);System.out.println("5.0 - 3.0 = " + subResult);			}catch(Exception e) {e.printStackTrace();}			}	
}
http://www.lryc.cn/news/166738.html

相关文章:

  • 无水印免费4K视频素材网站 可商用-Free Stock Video
  • kubesphere中间件部署
  • 使用 AWS S3 SDK 访问 COS-腾讯云国际站代充
  • c语言每日一练(15)
  • 如何利用软文推广进行SEO优化(打造优质软文,提升网站排名)
  • Java线程池ExecutorService和Executors应用(Spring Boot微服务)
  • 机器学习笔记之最优化理论与方法(八)无约束优化问题——常用求解方法(中)
  • Django系列:Django简介与MTV架构体系概述
  • 锐捷交换机WEB管理系统EXCU_SHELL密码信息泄漏漏洞
  • 线性代数(六) 线性变换
  • Python基础运算分享
  • 【MySQL】mysql中有哪几种类型的备份技术?它们各自有什么优缺点?
  • 5基于pytorch的多目标粒子群算法,MOPSO,引导种群逼近真实Pareto前沿,算法运行结束后将外部存档中粒子作为获得的Pareto最优解近似。
  • 002 Linux 权限
  • 【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数
  • “网站建设流程详解:从概念到上线的每个细节“
  • DC/DC开关电源学习笔记(七)低压大电流DC/DC变换技术
  • XUbuntu22.04之查找进程号pidof、pgrep总结(一百九十)
  • BI与数据治理以及数据仓库有什么区别
  • java---jar详解
  • uni-app 新增 微信小程序之新版隐私协议
  • nbcio-boot移植到若依ruoyi-nbcio平台里一formdesigner部分(四)
  • 公交查询系统
  • opencv 轮廓顶点重新排序----四边形
  • 【项目实战】【已开源】USB2.0 HUB 集线器的制作教程(详细步骤以及电路图解释)
  • 分布式运用之rsync远程同步
  • 誉天在线项目~ElementPlus实现浏览页面注意点
  • 神经网络-pytorch版本
  • uniapp vue 页面传参问题encodeURIComponent
  • 【GDAL】tif影像拼接和目标截取