跳轉到內容

遠端方法呼叫

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

待辦事項
新增一些類似於 變數 中的練習


華夏公益教科書