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点多了。大家鼓励一下吧,哈哈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值