rmi远程调用被拒绝_Java基础--RMI

939a32d06b55aab4b002bd8a2bb496a7.png

RMI (Remote Method Invocation,远程方法调用)是Java一组拥护开发分布式应用程序的API,用于不同虚拟机间的通信,核心是远程对象

RMI通信模型:

a8bc9b40999c76e4052842c51c3feee2.png

1、客户端调用辅助对象stub上方法

2、stub对调用信息(变量、方法)打包,网络发给服务端辅助对象

3、(1.2前)skeleton将stub送来的信息解包,找到被调方法的对象及本身

4、调用服务端对象上的方法,将结果返回给skeleton、打包、给stub

5、stub解包,返给客户端对象,获取返回值

可以把stub理解为本地的一个代理对象,客户端不知道server的存在,

数据传递问题:

分布式系统、不同内存空间,虚拟机A对象的引用对于虚拟机B没有意义

解决方案一:引用传递更改为值传递

将对象序列化为字节,使用字节副本在客户端、服务器间传递,一个虚拟机对该值的修改不影响其他主机的数据,问题:对象嵌套引用造成序列化嵌套,数据量激增

能不能被序列化要满足下面任一条件:1、java基本类型,2、实现Serializable接口,3、容器类中的对象可以序列化,容器也可以序列化,4、子类可序列化,其可序列化

当远程主机调用本地主机方法时,通过本地主机查询引用对应的对象;对象共享、一变都收影响

RMI参数传递和结果返回的三种机制:

1、简单类型:按值传递、传递数据拷贝;2、(实现了Remote接口的)远程对象引用、以远程对象的引用传递;3、(未实现Remote接口)远程对象引用,按值传递,通过序列化传递副本

远程对象的发现问题:

调用远程对象方法前需远程对象的引用,如何获取呐?首先咱们把“将远程对象的发现”类比于IP地址的发现

实际生活中网络通过IP地址来定位网站,这有一个映射的过程,在DNS(Domain Name System)域名系统中通过域名来查找对应的IP地址来访问服务器,这里IP相当于远程对象的引用,DNS相当于一个注册表Registry,域名在RMI中相当于远程对象的标识符,客户端通过提供远程对象的标识符访问注册表、得到远程对象的引用;标识符:

名称是URL形式的,类似于http的URL,schema是rmi,rmi://host:port/name,host注册表运行的注解,port接收调用的端口,name是标识对象的简单名称,主机和端口可选、依次默认本地、1099

编程实现:

服务器端:

远程对象:实现java.rmi.Remote接口或继承java.rmi.Remote接口的接口

在远程接口中声明的方法才能被远程调用

注意事项:

1、子接口中方法必须抛出java.rmi.RemoteException异常(使用RMI时可能抛出的大多数异常的父类)

2、子接口的实现类直接、间接继承java.rmi.server.UnicastRemoteObject(提供了很多支持RMI的方法,这些方法可以通过JRMP协议导出一个远程对象的引用并动态代理构建可以和远程对象交互的stub对象)

public interface UserHandler extends Remote { String getUserName(int id) throws RemoteException;}

实体类:序列化、serialVersionUID(后面客户端对应上)

public class User implements Serializable { // 该字段必须存在 private static final long serialVersionUID = 42L; // setter和getter可以没有 String name; int id;  public User(String name, int id) { this.name = name; this.id = id; }}

实现类:

public class UserHandlerImpl extends UnicastRemoteObject implements UserHandler { // 该构造期必须存在,因为集继承了UnicastRemoteObject类,其构造器要抛出RemoteException public UserHandlerImpl() throws RemoteException { super(); }  @Override public String getUserName(int id) throws RemoteException { return "开挂的人生"; }}

运行远程对象:

UserHandler userHandler = null;userHandler = new UserHandlerImpl();Naming.rebind("user
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值