1. 程式人生 > >Java 遠端呼叫RMI 簡單例項之一

Java 遠端呼叫RMI 簡單例項之一

這兩天在玩java的遠端呼叫,因為之前一直沒有接觸過,也沒有寫過demo。玩起來還是走了很多彎路的,在網上搜了很多blog,很多技術大牛的blog寫的很不錯,但對於新手來說,有些問題還是沒有講解清楚。花了蠻多時間,終於整理出自己的一個demo。因此附上,供以後學習之用。

在java 基礎講義部分並沒有提及java RMI技術,在Head First Java一書中有一章將java 提到RMI技術,但內容不多。大部分RMI技術的知識我獲取渠道是網上。所列出知識點是個人能接受的。
RMI遠端方法呼叫(Remote Method Invocation)。能夠讓在某個Java虛擬機器上的物件像呼叫本地物件一樣呼叫另一個java 虛擬機器中的物件上的方法。
RMI遠端呼叫步驟:
  1. 1,客戶物件呼叫客戶端輔助物件上的方法
    2,客戶端輔助物件打包呼叫資訊(變數,方法名),通過網路傳送給服務端輔助物件
    3,服務端輔助物件將客戶端輔助物件傳送來的資訊解包,找出真正被呼叫的方法以及該方法所在物件
    4,呼叫真正服務物件上的真正方法,並將結果返回給服務端輔助物件
    5,服務端輔助物件將結果打包,傳送給客戶端輔助物件
    6,客戶端輔助物件將返回值解包,返回給客戶物件
    7,客戶物件獲得返回值
    RMI遠端服務搭建步驟:

  2. 1、建立遠端介面,建立遠端介面並繼承Remote介面。
    2、實現遠端介面。
    3、利用rmic工具對實現類產生stub存根類和skeleton骨架類。
    4、註冊RMI服務。
    5、啟動服務。
    6、編寫客戶端程式碼
    看例子,在Eclipse中搭建Java專案。
    服務端:
    專案結構:
    這裡寫圖片描述


    1、 建立遠端介面:繼承Remote介面,Remote介面沒有任何方法,是一個標記性介面。

package com.rmi.remote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RmiInterface extends Remote {
    /**
     * 遠端呼叫服務方法
     *@Date 2017年8月2日
     * @param name
     * @return
     * @throws RemoteException
     */
    public
String doService(String name) throws RemoteException; /** * 遠端呼叫sum方法 *@Date 2017年8月2日 * @param a * @param b * @return * @throws RemoteException */ public int sum(int a, int b) throws RemoteException; }

2、實現遠端介面:


package com.rmi.service;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import com.rmi.remote.RmiInterface;

public class ServiceImp  extends UnicastRemoteObject implements RmiInterface{
    /**
     * 
     */
    private static final long serialVersionUID = 257078182179512007L;

    public ServiceImp() throws RemoteException{
        super();
    }

    @Override
    public String doService(String name) throws RemoteException {
        System.out.println("your name is" + name);
        return name+" to";
    }

    @Override
    public int sum(int a, int b) throws RemoteException {
        return a+b;
    }

}

這裡實現類繼承了UnicastRemoteObject ,目的是將介面連線至RMI系統。這也是建立遠端物件最簡單的方式。實現類也可以不繼承UnicastRemoteObject,而是直接利用在實現類中呼叫UnicastRemoteObject的exportObject(Object obj,int port),注意一定要指定port,可以達到相同的效果。
3、利用rmic工具對實現類產生stub存根類和skeleton骨架類。
jdk1.2以後的RMI可以通過反射API可以直接將請求傳送給真實類,所以不需要skeleton類了
在eclipse中這步驟不需要做,我在搭建專案的時候,沒有做。
4、註冊服務。
5、釋出服務。


package com.rmi.register;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

import com.rmi.service.ServiceImp;

/**
 * 釋出介面
 * 
 * @author Administrator
 * @date 2017年8月2日
 */
public class Main {
    public static void main(String[] args) {
        try {
            ServiceImp serviceImp = new ServiceImp();
            LocateRegistry.createRegistry(8888);
            Naming.rebind("rmi://:8888/MyService", serviceImp);
            System.out.println(">>INFO:遠端MyService物件繫結成功!");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

Main函式執行釋出服務。
因為是本機,所以省略本機的ip,釋出結果如圖:
這裡寫圖片描述
這時服務類是一直執行的。
6。編寫客戶端
專案結構:
這裡寫圖片描述
客戶端專案中需要有客戶端輔助物件打包呼叫資訊(變數,方法名)傳送到網路。RmiInterface.java就是客戶端的輔物件,包名,方法都是與服務端的遠端介面一致。


package com.rmi.remote;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RmiInterface extends Remote {

    /**
     * 遠端呼叫服務方法
     *@Date 2017年8月2日
     * @param name
     * @return
     * @throws RemoteException
     */
    public String doService(String name) throws RemoteException;

    /**
     * 遠端呼叫sum方法
     *@Date 2017年8月2日
     * @param a
     * @param b
     * @return
     * @throws RemoteException
     */
    public int sum(int a, int b) throws RemoteException;
}

客戶端測試類:


package com.rmi.test;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import com.rmi.remote.RmiInterface;

public class Main {
    public static void main(String[] args) {
         try {
            RmiInterface service = (RmiInterface) Naming.lookup("rmi://:8888/MyService");
            System.out.println(service.doService("sb"));
            System.out.println(service.sum(5, 8));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
    }
}

測試結果
客戶端輸出
這裡寫圖片描述
服務端輸出
這裡寫圖片描述
測試成功!