Java分布式之RMI實(shí)例教程
Java分布式之RMI實(shí)例教程,RMI的基礎(chǔ)是接口,RMI構(gòu)架基于一個(gè)重要的原理:定義接口和定義接口的具體實(shí)現(xiàn)是分開(kāi)的。
編輯特別推薦:
關(guān)于Java性能監(jiān)控不知道的五件事
Java運(yùn)行時(shí)環(huán)境初始化時(shí)出現(xiàn)錯(cuò)誤
SQLServe數(shù)據(jù)庫(kù)到DB2連接服務(wù)器的實(shí)現(xiàn)過(guò)程全解
前言
最近的聯(lián)通項(xiàng)目,下一階段可能會(huì)涉及到和各省間的RMI接口,所以總結(jié)一下08年中國(guó)移動(dòng)自動(dòng)撥測(cè)系統(tǒng)用到的RMI技術(shù),以備不時(shí)之需。同時(shí)也給廣大初哥提供一些學(xué)習(xí)資料,哈哈。前幾年,一直忙于項(xiàng)目,沒(méi)怎么做系統(tǒng)總結(jié)。以后計(jì)劃寫(xiě)一些以前項(xiàng)目用過(guò)的Java分布式技術(shù)實(shí)例教程,如:RMI、Socket、Mina、SNMP、SOAP、Web Service、Hessian、JMS等。希望和大家一起交流,分享經(jīng)驗(yàn),一起提高。
RMI簡(jiǎn)介
RMI,遠(yuǎn)程方法調(diào)用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應(yīng)用程序的方便途徑。RMI是非常容易使用的,但是它非常的強(qiáng)大。
RMI的基礎(chǔ)是接口,RMI構(gòu)架基于一個(gè)重要的原理:定義接口和定義接口的具體實(shí)現(xiàn)是分開(kāi)的??纯磈boss-remoting:
基本原理
要實(shí)現(xiàn)網(wǎng)絡(luò)機(jī)器間的通訊,首先得來(lái)看看計(jì)算機(jī)系統(tǒng)網(wǎng)絡(luò)通信的基本原理,在底層層面去看,網(wǎng)絡(luò)通信需要做的就是將流從一臺(tái)計(jì)算機(jī)傳輸?shù)搅硗庖慌_(tái)計(jì)算機(jī),基于傳輸協(xié)議和網(wǎng)絡(luò)IO來(lái)實(shí)現(xiàn),其中傳輸協(xié)議比較出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上為某類(lèi)應(yīng)用場(chǎng)景而擴(kuò)展出的傳輸協(xié)議,網(wǎng)絡(luò)IO,主要有bio、nio、aio三種方式,所有的分布式應(yīng)用通訊都基于這個(gè)原理而實(shí)現(xiàn),只是為了應(yīng)用的易用,各種語(yǔ)言通常都會(huì)提供一些更為貼近應(yīng)用易用的應(yīng)用層協(xié)議。
主要步驟
分為以下幾個(gè)步驟:
1. 創(chuàng)建遠(yuǎn)程接口及聲明遠(yuǎn)程方法(RmiMonitorService.java)
2. 實(shí)現(xiàn)遠(yuǎn)程接口及遠(yuǎn)程方法(繼承UnicastRemoteObject)(RmiMonitorServiceImpl.java)
3. 啟動(dòng)RMI注冊(cè)服務(wù),并注冊(cè)遠(yuǎn)程對(duì)象(RmiServer.java)
4. 客戶(hù)端查找遠(yuǎn)程對(duì)象,并調(diào)用遠(yuǎn)程方法(MonitorClient.java)
5. 運(yùn)行實(shí)例#p#
業(yè)務(wù)場(chǎng)景
在移動(dòng)撥測(cè)系統(tǒng)管理端中要融合實(shí)時(shí)顯示。簡(jiǎn)單點(diǎn)說(shuō)就是設(shè)備出現(xiàn)告警時(shí),要采用不同方式實(shí)時(shí)展示。如Web界面(Ajax)、GIS等。
主要業(yè)務(wù)流程設(shè)計(jì):
1. 設(shè)備告警
2. 調(diào)用RMI Client
3. 調(diào)用RMI Server
4. 調(diào)用業(yè)務(wù)處理接口
5. 告警信息入庫(kù)
6. 實(shí)時(shí)顯示(Ajax,Gis等技術(shù))
技術(shù)設(shè)計(jì)
接口函數(shù)函數(shù)名稱(chēng): int interactive( int funindex, string param )
參數(shù)說(shuō)明:
funindex 功能號(hào),整型。1為設(shè)備告警
param 交互參數(shù),字符串型。
返回:
成功=1,失敗=0。
說(shuō)明:
param交互參數(shù)用鍵值對(duì)組成,每個(gè)鍵值對(duì)以“&”分割,如:Tsid=01&devid=002&warnid=102&warntype=01&warnlevel=1 。
測(cè)試點(diǎn)ID(tsid)
設(shè)備ID(devid)
告警ID(warnid)
告警類(lèi)型(warntype)
告警級(jí)別(warnlevel)
代碼實(shí)現(xiàn)#p#
廢話(huà)少說(shuō),上代碼,為了演示方便,經(jīng)過(guò)整理,省去了很多get,set之類(lèi)的東東還有業(yè)務(wù)的東西以及Spring相關(guān)的東西。
- Java代碼
- RmiMonitorService.java
- package nbpt.ts.manager.message.service;
- import java.rmi.Remote;
- import java.rmi.RemoteException;
- /**
- * Description: 實(shí)時(shí)顯示RMI服務(wù)接口.
- *
- * RMI接口必須擴(kuò)展接口java.rmi.Remote
- *
- * @author Peter Wei
- * @version 1.0 Feb 25, 2009
- */
- public interface RmiMonitorService extends Remote {
- /**
- * 實(shí)時(shí)顯示對(duì)外接口
- *
- * @param funindex
- * 功能號(hào)
- * @param param
- * 鍵名列表,也就是實(shí)際傳輸?shù)膬?nèi)容
- * @return
- * @throws RemoteException
- * 遠(yuǎn)程接口方法必須拋出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: 實(shí)時(shí)顯示RMI接口實(shí)現(xiàn).
- *
- * 實(shí)現(xiàn)RMI接口及遠(yuǎn)程方法(繼承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;
- /**
- * 必須定義構(gòu)造方法,因?yàn)橐獟伋鯮emoteException異常
- *
- * @throws RemoteException
- */
- public RmiMonitorServiceImpl() throws RemoteException {
- super();
- }
- public int interactive(int funindex, String param) throws RemoteException {
- int result = FAIL;
- switch (funindex) {
告警#p#
- case (1): {
- // warnService = (WarnService) AppContext.getAppContext().getBean(
- // "warn.warnService");
實(shí)際應(yīng)用是從Spring應(yīng)用中獲取告警Service,如上代碼
- warnService = new WarnServiceImpl();
網(wǎng)絡(luò)告警的業(yè)務(wù)操作
- 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服務(wù)端.
- *
- * @author Peter Wei
- * @version 1.0 Feb 25, 2009
- */
- public class RmiServer {
- public String ip = "localhost";
- public int port = 8889;
- /**
- * 啟動(dòng)RMI注冊(cè)服務(wù),并注冊(cè)遠(yuǎn)程對(duì)象.實(shí)際應(yīng)用中是在Spring初始化并啟動(dòng)
- */
- public void init() {
- try {
- LocateRegistry.createRegistry(port);
- // 創(chuàng)建一個(gè)遠(yuǎn)程對(duì)象
- RmiMonitorService comm = new RmiMonitorServiceImpl();
- Naming.bind("//" + ip + ":" + port + "/comm", comm);
- } catch (RemoteException e) {
- System.out.println("創(chuàng)建遠(yuǎn)程對(duì)象發(fā)生異常!" + e.toString());
- e.printStackTrace();
- } catch (AlreadyBoundException e) {
- System.out.println("發(fā)生重復(fù)綁定對(duì)象異常!" + e.toString());
- e.printStackTrace();
- } catch (MalformedURLException e) {
- System.out.println("發(fā)生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) {
實(shí)際應(yīng)用中是在Spring初始化并啟動(dòng)#p#
- RmiServer rmiServer = new RmiServer();
- System.out.println("RMI服務(wù)初始化:");
- 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客戶(hù)端.
- *
- * @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服務(wù)注冊(cè)表中查找名稱(chēng)為RmiMonitorService的對(duì)象,并調(diào)用其上的方法#p#
- 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("發(fā)送告警信息:");
- String msg = "tsid=1022&devid=10001027&warnid=102&warntype=01&warnlevel=1&warnmsg=設(shè)備出錯(cuò),請(qǐng)檢查.";
- 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: 告警服務(wù)
- *
- * @author Peter Wei
- * @version 1.0 2010-8-22
- */
- public interface WarnService {
- /**
* 處理告警:告警來(lái)時(shí)的業(yè)務(wù)操作,實(shí)際操作是解析消息存庫(kù),然后界面Ajax定時(shí)刷新數(shù)據(jù),獲取實(shí)時(shí)告警展示#p#
- *
- * @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: 告警服務(wù)
- *
- * @author Peter Wei
- * @version 1.0 2010-8-22
- */
- public class WarnServiceImpl implements WarnService {
- public int dealWarn(String message) {
告警處理方法
- System.out.println("已接收網(wǎng)絡(luò)告警");
- // …
- return 1;
- }
- }