Java分佈式之RMI實例教程

Java分佈式之RMI實例教程

 

 

Peter Wei

 

2010-8-22

 

 

前言

最近的聯通項目,下一階段可能會涉及到和各省間的RMI接口,所以總結一下09年中國移動自動撥測系統用到的RMI技術,以備不時之需。同時也給廣大初哥提供一些學習資料,哈哈。前幾年,一直忙於項目,沒怎麼做系統總結。以後計劃寫一些以前項目用過的Java分佈式技術實例教程,如:RMISocketMinaSNMPSOAPWeb ServiceHessianJMS等。希望和大家一起交流,分享經驗,一起提高。

RMI簡介

RMI,遠程方法調用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分佈式Java應用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。

RMI的基礎是接口,RMI構架基於一個重要的原理:定義接口和定義接口的具體實現是分開的。看看jboss-remoting:

 

基本原理

要實現網絡機器間的通訊,首先得來看看計算機系統網絡通信的基本原理,在底層層面去看,網絡通信需要做的就是將流從一臺計算機傳輸到另外一臺計算機,基於傳輸協議和網絡IO來實現,其中傳輸協議比較出名的有httptcpudp等等,httptcpudp都是在基於Socket概念上爲某類應用場景而擴展出的傳輸協議,網絡IO,主要有bionioaio三種方式,所有的分佈式應用通訊都基於這個原理而實現,只是爲了應用的易用,各種語言通常都會提供一些更爲貼近應用易用的應用層協議。

主要步驟

分爲以下幾個步驟:

1.      創建遠程接口及聲明遠程方法(RmiMonitorService.java

2.      實現遠程接口及遠程方法(繼承UnicastRemoteObject(RmiMonitorServiceImpl.java)

3.      啓動RMI註冊服務,並註冊遠程對象(RmiServer.java

4.      客戶端查找遠程對象,並調用遠程方法(MonitorClient.java

5.      運行實例

業務場景

在移動撥測系統管理端中要融合實時顯示。簡單點說就是設備出現告警時,要採用不同方式實時展示。如Web界面(Ajax)GIS等。

 

主要業務流程設計:

1.      設備告警

2.      調用RMI Client

3.      調用RMI Server

4.      調用業務處理接口

5.      告警信息入庫

6.      實時顯示(Ajax,Gis等技術)

 

 

技術設計

接口函數函數名稱: int interactive( int funindex, string param )

參數說明:

funindex 功能號,整型。1爲設備告警

param 交互參數,字符串型。

返回:

成功=1,失敗=0

說明:

param交互參數用鍵值對組成,每個鍵值對以“&”分割,如:Tsid=01&devid=002&warnid=102&warntype=01&warnlevel=1

測試點ID(tsid)

設備ID(devid)

告警ID(warnid)

告警類型(warntype)

告警級別(warnlevel)

      

代碼實現

廢話少說,上代碼,爲了演示方便,經過整理,省去了很多getset之類的東東還有業務的東西以及Spring相關的東西。

 

RmiMonitorService.java

package nbpt.ts.manager.message.service;

 

import java.rmi.Remote;

import java.rmi.RemoteException;

 

/**

 * Description: 實時顯示RMI服務接口.

 *

 * RMI接口必須擴展接口java.rmi.Remote

 *

 * @author Peter Wei

 * @version 1.0 Feb 25, 2009

 */

public interface RmiMonitorService extends Remote {

    /**

     * 實時顯示對外接口

     *

     * @param funindex

     *            功能號

     * @param param

     *            鍵名列表,也就是實際傳輸的內容

     * @return

     * @throws RemoteException

     *             遠程接口方法必須拋出java.rmi.RemoteException

     */

    public int interactive(int funindex, String param) throws RemoteException;

}

RmiMonitorServiceImpl.java

package nbpt.ts.manager.message.service.impl;

 

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

// import nbpt.ts.manager.base.util.AppContext;

import nbpt.ts.manager.message.service.RmiMonitorService;

import nbpt.ts.manager.message.service.WarnService;

/**

 * Description: 實時顯示RMI接口實現.

 *

 * 實現RMI接口及遠程方法(繼承UnicastRemoteObject

 *

 * @author Peter Wei

 * @version 1.0 Feb 25, 2009

 */

public class RmiMonitorServiceImpl extends UnicastRemoteObject implements

       RmiMonitorService {

 

    private static final long serialVersionUID = -3771656108378649574L;

 

    public static final int SUCCSS = 1;

 

    public static final int FAIL = 0;

 

    public WarnService warnService;

 

    /**

     * 必須定義構造方法,因爲要拋出RemoteException異常

     *

     * @throws RemoteException

     */

    public RmiMonitorServiceImpl() throws RemoteException {

       super();

    }

 

    public int interactive(int funindex, String param) throws RemoteException {

 

       int result = FAIL;

       switch (funindex) {

       // 告警

       case (1): {

 

           // warnService = (WarnService) AppContext.getAppContext().getBean(

           // "warn.warnService");

           // 實際應用是從Spring應用中獲取告警Service,如上代碼

           warnService = new WarnServiceImpl();

           // 網絡告警的業務操作

           warnService.dealWarn(param);

           result = SUCCSS;

       }

           break;

       case (2):

           // do other biz

           break;

       }

       // ......

 

       return result;

    }

 

    public WarnService getWarnService() {

       return warnService;

    }

 

    public void setWarnService(WarnService warnService) {

       this.warnService = warnService;

    }

 

}

 

RmiServer.java

package nbpt.ts.manager.message.service;

 

import java.net.MalformedURLException;

import java.rmi.AlreadyBoundException;

import java.rmi.Naming;

import java.rmi.RemoteException;

import java.rmi.registry.LocateRegistry;

import nbpt.ts.manager.message.service.impl.RmiMonitorServiceImpl;

/**

 * Description: RMI服務端.

 *

 * @author Peter Wei

 * @version 1.0 Feb 25, 2009

 */

public class RmiServer {

 

    public String ip = "localhost";

 

    public int port = 8889;

 

    /**

     * 啓動RMI註冊服務,並註冊遠程對象.實際應用中是在Spring初始化並啓動

     */

    public void init() {

       try {

           LocateRegistry.createRegistry(port);

           // 創建一個遠程對象

           RmiMonitorService comm = new RmiMonitorServiceImpl();

           Naming.bind("//" + ip + ":" + port + "/comm", comm);

       } catch (RemoteException e) {

           System.out.println("創建遠程對象發生異常!" + e.toString());

           e.printStackTrace();

        } catch (AlreadyBoundException e) {

           System.out.println("發生重複綁定對象異常!" + e.toString());

           e.printStackTrace();

       } catch (MalformedURLException e) {

           System.out.println("發生URL畸形異常!" + e.toString());

           e.printStackTrace();

       }

    }

 

    public String getIp() {

       return ip;

    }

 

    public void setIp(String ip) {

       this.ip = ip;

    }

 

    public int getPort() {

       return port;

    }

 

    public void setPort(int port) {

       this.port = port;

    }

 

    public static void main(String[] args) {

       // 實際應用中是在Spring初始化並啓動

       RmiServer rmiServer = new RmiServer();

       System.out.println("RMI服務初始化:");

       rmiServer.init();

 

    }

}

MonitorClient.java

package nbpt.ts.manager.message.service;

 

import java.net.MalformedURLException;

import java.rmi.Naming;

import java.rmi.NotBoundException;

import java.rmi.RemoteException;

/**

 * Description: RMI客戶端.

 *

 * @author Peter Wei

 * @version 1.0 Feb 25, 2009

 */

public class MonitorClient {

 

    public RmiMonitorService monitorService;

 

    public String ip = "localhost";

 

    public int port = 8889;

 

    public int interactive(int funindex, String param) {

       int result = 0;

       try {

           getMonitorService().interactive(funindex, param);

           result = 1;

       } catch (RemoteException e) {

           e.printStackTrace();

       }

       return result;

    }

 

    public RmiMonitorService getMonitorService() {

       try {

           // RMI服務註冊表中查找名稱爲RmiMonitorService的對象,並調用其上的方法

           monitorService = (RmiMonitorService) Naming.lookup("rmi://" + ip

                  + ":" + port + "/comm");

 

       } catch (NotBoundException e) {

           e.printStackTrace();

       } catch (MalformedURLException e) {

           e.printStackTrace();

       } catch (RemoteException e) {

           e.printStackTrace();

       }

       return monitorService;

    }

 

    public static void main(String args[]) throws RemoteException {

       MonitorClient client = new MonitorClient();

       System.out.println("發送告警信息:");

       String msg = "tsid=1022&devid=10001027&warnid=102&warntype=01&warnlevel=1&warnmsg=設備出錯,請檢查.";

       System.out.println(client.getValue(msg, "warnmsg"));

       client.interactive(1, msg);

 

    }

 

    public String getValue(String content, String key) {

       String value = "";

 

       int begin = 0, end = 0;

       begin = content.indexOf(key + "=");

       end = content.indexOf("&", begin);

 

       if (end == -1)

           end = content.length();

       value = content.substring(begin + key.length() + 1, end);

       return value;

 

    }

}

 

WarnService.java

package nbpt.ts.manager.message.service;

 

/**

 * Description: 告警服務

 *

 * @author Peter Wei

 * @version 1.0 2010-8-22

 */

public interface WarnService {

 

    /**

     * 處理告警:告警來時的業務操作,實際操作是解析消息存庫,然後界面Ajax定時刷新數據,獲取實時告警展示

     *

     * @param message

     * @return

     */

    public int dealWarn(String message);

}

WarnServiceImpl.java

package nbpt.ts.manager.message.service.impl;

 

import nbpt.ts.manager.message.service.WarnService;

 

/**

 * Description: 告警服務

 *

 * @author Peter Wei

 * @version 1.0 2010-8-22

 */

public class WarnServiceImpl implements WarnService {

 

    public int dealWarn(String message) {

       // 告警處理方法

       System.out.println("已接收網絡告警");

// …

       return 1;

    }

 

}

小結

花了4個多小時才完成本實例教程,已經半夜2點多了。大家鼓勵一下吧,哈哈。

發佈了29 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章