1. 程式人生 > >rmi遠端方法呼叫

rmi遠端方法呼叫

Java RMI 是遠端方法呼叫機制(Remote Method Invocation)。它能夠在某個java虛擬機器上呼叫另一個java虛擬機器中物件的方法。用此方法呼叫的遠端物件必須實現遠端介面。
現在大名鼎鼎的ejb和web service都是基於RMI實現的。
RMI呼叫步驟:
這裡寫圖片描述

1、客戶端物件呼叫客戶端輔助物件的方法
2、客戶端輔助物件打包呼叫資訊(變數和方法),並將資訊通過socket傳遞給服務端輔助物件
3、服務端輔助物件解析接收到的資訊,然後尋找對應的服務端物件並呼叫
4、服務端物件返回結果
5、服務端輔助物件將結果打包返回給客戶端輔助物件
6、客戶端輔助物件將結果返回客戶端物件
7、客戶端物件接收到資訊

其中2-6對客戶是透明的,使用的時候它只管呼叫和接收

rmi例子
介面
**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-8-7 21:50:02
* 定義一個遠端介面,必須繼承Remote介面,其中需要遠端呼叫的方法必須丟擲RemoteException異常
*/
public interface IHello extends Remote {

/** 
 * 簡單的返回“Hello World!"字樣 
 * @return 返回“Hello World!"字樣 
 * @throws java.rmi.RemoteException 
 */ 
public String helloWorld() throws RemoteException; 

/** 
 * 一個簡單的業務方法,根據傳入的人名返回相應的問候語 
 * @param someBodyName  人名 
 * @return 返回相應的問候語 
 * @throws java.rmi.RemoteException 
 */ 
public String sayHelloToSomeBody(String someBodyName) throws RemoteException; 

}

例項
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-8-7 21:56:47
* 遠端的介面的實現
*/
public class HelloImpl extends UnicastRemoteObject implements IHello {
/**
* 因為UnicastRemoteObject的構造方法丟擲了RemoteException異常,因此這裡預設的構造方法必須寫,必須宣告丟擲RemoteException異常
*
* @throws RemoteException
*/
public HelloImpl() throws RemoteException {
}

/** 
 * 簡單的返回“Hello World!"字樣 
 * 
 * @return 返回“Hello World!"字樣 
 * @throws java.rmi.RemoteException 
 */ 
public String helloWorld() throws RemoteException { 
    return "Hello World!"; 
} 

/** 
 * 一個簡單的業務方法,根據傳入的人名返回相應的問候語 
 * 
 * @param someBodyName 人名 
 * @return 返回相應的問候語 
 * @throws java.rmi.RemoteException 
 */ 
public String sayHelloToSomeBody(String someBodyName) throws RemoteException { 
    return "你好," + someBodyName + "!"; 
} 

}

服務繫結

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-8-7 22:03:35
* 建立RMI登錄檔,啟動RMI服務,並將遠端物件註冊到RMI登錄檔中。
*/
public class HelloServer {
public static void main(String args[]) {

    try { 
        //建立一個遠端物件 
        IHello rhello = new HelloImpl(); 
        //本地主機上的遠端物件登錄檔Registry的例項,並指定埠為8888,這一步必不可少(Java預設埠是1099),必不可缺的一步,缺少登錄檔建立,則無法繫結物件到遠端登錄檔上 
        LocateRegistry.createRegistry(8888); 

        //把遠端物件註冊到RMI註冊伺服器上,並命名為RHello 
        //繫結的URL標準格式為:rmi://host:port/name(其中協議名可以省略,下面兩種寫法都是正確的) 
        Naming.bind("rmi://localhost:8888/RHello",rhello); 

// Naming.bind(“//localhost:8888/RHello”,rhello);

        System.out.println(">>>>>INFO:遠端IHello物件繫結成功!"); 
    } catch (RemoteException e) { 
        System.out.println("建立遠端物件發生異常!"); 
        e.printStackTrace(); 
    } catch (AlreadyBoundException e) { 
        System.out.println("發生重複繫結物件異常!"); 
        e.printStackTrace(); 
    } catch (MalformedURLException e) { 
        System.out.println("發生URL畸形異常!"); 
        e.printStackTrace(); 
    } 
} 

}
客戶端
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-8-7 22:21:07
* 客戶端測試,在客戶端呼叫遠端物件上的遠端方法,並返回結果。
*/
public class HelloClient {
public static void main(String args[]){
try {
//在RMI服務登錄檔中查詢名稱為RHello的物件,並呼叫其上的方法
IHello rhello =(IHello) Naming.lookup(“rmi://localhost:8888/RHello”);
System.out.println(rhello.helloWorld());
System.out.println(rhello.sayHelloToSomeBody(“熔岩”));
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}