跳转到内容

远程方法调用

25% developed
来自维基教科书,开放世界中的开放书籍

导航 并发编程 主题:v  d  e )


Java 的远程方法调用 (通常称为 RMI) 用于客户端和服务器模型。RMI 是 RPC (远程过程调用) 的面向对象等效项。

Java 远程方法调用 (RMI) 系统允许在某个 Java 虚拟机 (VM) 中运行的对象调用在另一个 Java VM 中运行的对象的方法。RMI 提供了用 Java 编程语言编写的程序之间的远程通信。

RMI 仅定义为在 Java 平台上使用。如果需要在不同的语言环境之间调用方法,请使用 CORBA。使用 CORBA,Java 客户端可以调用 C++ 服务器,反之亦然。而 RMI 无法实现这种功能。

存根和骨架

[编辑 | 编辑源代码]

远程方法调用通过客户端的存根和服务器端的骨架进行。

CLIENT --> STUB --> ... Network ... --> SKELETON --> REMOTE OBJECT

在 Java 1.2 之前,必须使用 rmic 工具显式生成骨架。从 1.2 开始,使用了动态骨架,它利用 Java 反射的功能来完成工作。

rmiregistry

[编辑 | 编辑源代码]

远程对象可以在 RMI 注册表中列出。客户端可以通过查询注册表获取对远程对象的引用。之后,客户端可以调用远程对象上的方法。(远程对象引用也可以通过调用其他远程方法获取。注册表实际上是一个“引导程序”,解决了从哪里获取初始远程引用问题。)

RMI 注册表可以在服务器 JVM 中启动,通过 LocateRegistry.createRegistry() API 启动,或者在一个名为 rmiregistry 的单独进程中启动,该进程必须在将远程对象添加到注册表之前启动,例如在 Unix 中通过命令行启动。

Standard input or output Unix 上的 rmiregistry
rmiregistry <port> &

或者在 Windows 上

Standard input or output Windows 上的 rmiregistry
start rmiregistry <port>

如果没有指定 port,则使用默认端口 1099。客户端需要连接到此 port 以访问注册表。

也可以通过调用以下代码从程序中启动注册表

Example 代码部分 1:rmiregistry 启动
import java.rmi.registry.LocateRegistry;
...
Registry reg = LocateRegistry.createRegistry(iPort);

作为参数传递给远程对象方法的对象将按值传递。如果远程对象更改了传入的对象值,则不会反映在客户端,这与调用本地对象时的情况相反。用作远程方法调用参数的对象必须实现 java.io.Serializable 接口,因为它们在通过网络传递时将被序列化,并且将在另一端创建一个新对象。

但是,作为参数传递的已导出的远程对象按远程引用传递。

rmic 工具

[编辑 | 编辑源代码]
Clipboard

待办事项
完成本节。


RMI 远程对象

[编辑 | 编辑源代码]

远程对象必须扩展 java.rmi.server.UnicastRemoteObject 对象,或者通过调用 java.rmi.server.UnicastRemoteObject.exportObject() 方法显式导出。

RMI 客户端

[编辑 | 编辑源代码]

这是一个 RMI 客户端的示例

Computer code 代码清单 7.10:HelloClient.java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class HelloClient{

    private HelloClient() {}

    public static void main(String[] args) {
        String host = (args.length < 1) ? null : args[0];
        try {
            Registry registry = LocateRegistry.getRegistry(host);
            Hello stub = (Hello) registry.lookup("Hello");
            String response = stub.sayHello();
            System.out.println("response: " + response);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}


Clipboard

待办事项
添加一些类似于 变量 中的练习


华夏公益教科书