核心技术(卷二)07、第11章-RMI远程方法调用

RMI远程方法调用

客户与服务器角色

所有的分布式编程思想都很简单:客户计算机产生一个请求,然后将这个请求通过网络发送到服务器。服务器处理这个请求并返回一个针对该客户端的相应,供客户端进行分析。

我们想要的机制:

客户端程序员以常规的方式进行方法调用,无需关心将数据发送到网络上或者解析响应之类的问题。解决办法是在客户端为远程对象安装一个代理。

同样实现服务端的程序员也不需要考虑与客户端之间的通信。解决办法是在服务端安装第二个代理对象。该服务端代理和客户端代理通信,并且它将以常规方式调用服务器对象上的方法。

代理之间的通信:

  1. CORBA:通用对象请求代理架构,支持 任何语言 编写的对象之间的方法调用。
  2. Web服务架构是一个协议集,有时统一描述为 WS-*。它也是独立于编程语言的,不过它使用基于XML的通信格式。用于传输对象的格式则是 简单对象访问协议(SOAP)
  3. RMI,Java的远程方法调用技术,支持Java的分布式对象之间的方法调用。

远程方法调用

存根与参数编组

我们将 客户机 上的代理对象称为 存根(stub)。它知道如何通过网络与服务器联系。

存根会将远程方法所需的参数打包成一组字节。对参数编码的过程称作 参数编组(parameter marshalling),参数编组的目的是为了将参数编码为适合在虚拟机之间传输的格式。

客户端的存根方法构造了一个信息块,它有一下几部分组成:

  • 被调用的远程对象的标识符
  • 被调用的方法的描述
  • 编组后的参数
    服务端接收器执行一下操作:
  1. 定位要调用的远程对象
  2. 调用所需方法,并传递客户端提供的参数
  3. 捕获返回值或该调用产生的异常
  4. 将返回值编组,打包送回给客户端存根

客户端存根对来自服务端的返回值或异常进行反编组,其结果就作为调用存根的返回值。

远程方法调用过程

RMI编程模型

接口与实现

public interface Warehouse extends Remote{
	double getPrice(String description) throws RemoteException;
}

远程对象的接口必须扩展java.rmi.Remot接口;接口中的所有方法还必须抛出RemoteException异常。

客户端 我们需要提供一个实现了上面远程接口的类:

public class WarehoseImpl extends UnicastRemoteObject implements Warehouse{

	public WarehouseImpl() throws RemoteException{
		...
	}

	public double getPrice(String description) throws RemoteException{
		...
		return price;
	}
}

这个实现类继承了UnicastRemoteObject,这个类的构造器使得它的对象可供远程访问。如果我们的实现类已经继承了其它的类,从未不法继承UnicastRemotObject类时,我们可以在实现类的构造方法中调用下面的语句:

UnicastRemoteObject.exportObject(this,0);

第二个参数是0,表示任何适合的端口都可以用来监听客户端连接。

RMI注册表

要访问服务器上的远程对象时,客户端首先需要一个本地的存根对象。客户端应该怎么去的这个存根呢?最普通的方法就是调用另一个服务对象上的一个远程方法,以返回值的方式去的存根对象。获取存根的第一个远程对象总是要通过某种方式进行定位,否则这就成了先有鸡还是现有蛋的问题了。JDK提供了RIM注册服务,允许我们注册远程对象:

//在1099端口上开启注册服务
Registry registry = LocateRegistry.createRegistry(1099);
//将WarehouseImpl对象注册到RMI注册表中
WarehoseImpl warehoseImpl  = new WarehoseImpl();
registry.bind("warehouse",warehoseImpl);

客户端:

Registry registry = LocateRegistry.getRegistry(host);//端口默认为1099
//Registry registry = LocateRegistry.getRegistry(host,port);
String[] servicesName = registry.list();//获取所有的服务名称
Warehouse warehouse = (Warehouse)registry.lookup("warehouse");//获取存根
warehouse.getPrice("apple");//调用远程方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值