ICE的应用

来源:互联网 发布:手机破解软件资源 编辑:程序博客网 时间:2024/06/06 03:11

ice并不大众,但功能却很强大,能跨平台,能分布式.关于ice,有位大神总结的非常棒,关于它的前生今世都说的非常清楚,ICE简单介绍及使用示例.
我这里再总结一下,便于自己的记忆吧.

  1. 安装ICE

    先在https://zeroc.com/distributions/ice下载安装文件,我用的是3.31.

  2. 配置环境

    安装完成后,将环境变量ICE_HOME设置后,将%ICE_HOME%/bin目录加到path中,再将%ICE_HOME%/lib/bd.jar和%ICE_HOME%/lib/Ice.jar也加class环境中.

  3. 编写ICE文件

    不带包

module demo {  interface Zan{ void printString(string  s); void add(int a ,int b);};};

带包

[["java:package:cn.cai.ice"]] module component {  interface Zan{ string doRequest(string  jsonStr);};};
  1. 生成文件
    在Zan.ice文件保存目录(不能在磁盘目录)执行命令:
    slice2java Zan.ice
    搞定。

  2. 代码编写
    Server

public class Server {    public static void main(String[] args) {        PropertyConfigurator.configure("src/log4j.properties");        int status = 0;        Ice.Communicator ic = null;        try {            // 初使化连接,args可以传一些初使化参数,如连接超时时间,初使化客户连接池的数量等            ic = Ice.Util.initialize(args);            //创建名为SimplePrinterAdapter的适配器,并要求适配器使用缺省的协议(TCP/IP侦听端口为10000的请求)            Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");            /**方法一             //实例化一个ZanImpl对象,为Printer接口创建一个服务对象            Ice.Object object = new ZanImpl();            //将服务单元增加到适配器中,并给服务对象指定名称为SimplePrinter,该名称用于唯一确定一个服务单元              adapter.add(object,Ice.Util.stringToIdentity("SimplePrinter"));            */            /**方法二*/            ComponentServantLocator  componentServantLocator = new ComponentServantLocator(new HashMap<String, String>());            adapter.addServantLocator(componentServantLocator, "");            //激活适配器,这样做的好处是可以等到所有资源就位后再触发             adapter.activate();            ic.waitForShutdown();        } catch (Ice.LocalException e) {            e.printStackTrace();            status = 1;        } catch (Exception e) {            System.err.println(e.getMessage());        } finally {            if (ic != null) {                ic.destroy();            }        }        System.exit(status);    }}

客户端

public class Client {    public static void main(String[] args) {        int status = 0;        Ice.Communicator ic = null;        try {            //初使化            ic = Ice.Util.initialize(args);            //传入远程服务单元的名称、网络协议、IP及端口,获取ZanPrx的远程代理,这里使用的stringToProxy方式              /**对应方法一            Ice.ObjectPrx base = ic.stringToProxy("SimplePrinter:default -p 10000");             */            /**对应方法二*/            Ice.ObjectPrx base = ic.stringToProxy(ZanPrx.class.getName()+":default -p 10000");            //通过checkedCast向下转换,获取Printer接口的远程,并同时检测根据传入的名称获取的服务单元是否Printer的代理接口,如果不是则返回null对象              ZanPrx zan = ZanPrxHelper.checkedCast(base);            if (zan == null) {                System.err.println("Ivalid proxy");            }            zan.add(1, 2);            zan.printString("Hello World");        } catch (Ice.LocalException e) {            status = 1;            e.printStackTrace();        } catch (Exception e) {            status = 1;            System.err.print(e.getMessage());        } finally {            if (ic != null) {                ic.destroy();            }        }        System.exit(status);    }}
 实现类
public class ZanImpl extends _ZanDisp{    @Override    public void printString(String s, Current __current) {        System.out.println(s);    }    @Override    public void add(int a, int b, Current __current) {        System.out.println(a+b);    }}

定位器

public class ComponentServantLocator extends LocalObjectImpl implements ServantLocator {    public static Logger logger = LoggerFactory.getLogger(ComponentServantLocator.class);    private static AtomicLong requestCountTotal = new AtomicLong(0L);    private Map<String, String> config = null;    private boolean accessControl = false;    private Map<InetAddress, Boolean> permission = new ConcurrentHashMap<InetAddress, Boolean>();    ComponentServantLocator(Map<String, String> config) {        this.config = config;        String ac = (String) config.get("server.access_control");        String as = (String) config.get("server.access_servers");        this.accessControl = (("true".equals(ac)) && (null != as) && (!"".equals(as)));        if ((null != as) && (!"".equals(as))) {            String[] items = as.trim().split(";");            for (String item : items) {                try {                    String[] host = item.split(":");                    InetAddress h = InetAddress.getByName(host[0]);                    Boolean flag = Boolean.valueOf(host[1]);                    this.permission.put(h, flag);                } catch (Exception ex) {                    logger.error("无法解析访问控制项:{}", item);                }            }        }    }    public void deactivate(String arg) {        logger.debug("====什么方法======"+arg);    }    public void finished(Current current, Ice.Object servant, Object cookie) throws UserException {        logger.debug("完成");    }    public Ice.Object locate(Current current, LocalObjectHolder holder) throws UserException {        logger.info("connect!");        requestCountTotal.addAndGet(1L);        ConnectionI conn = (ConnectionI) current.con;        Transceiver trans = conn.getTransceiver();        SocketChannel sc = (SocketChannel) trans.fd();        Socket socket = sc.socket();        InetAddress clientAddress = socket.getInetAddress();        InetAddress localAddress = socket.getLocalAddress();        if (logger.isDebugEnabled()) {            logger.debug("Transceiver:" + trans);            logger.debug("SocketChannel:" + sc);            logger.debug("Socket:" + socket);            logger.debug("localAddress:" + localAddress);            logger.debug("clientAddress:" + clientAddress);        }        if (!checkPermission(clientAddress, localAddress)) {            throw new RuntimeException("非法地址访问");        }        if (current.id.name != null) {            Ice.Object target = ComponentServantProvider.getServantBean(current.id.name);            return target;        }        return null;    }    private boolean checkPermission(InetAddress clientAddress, InetAddress localAddress) {        if (this.accessControl) {            Boolean flag = (Boolean) this.permission.get(clientAddress);            return null == flag ? true : flag.booleanValue();        }        return true;    }    public static long getRequestCountTotal() {        return requestCountTotal.get();    }}
public class ComponentServantProvider {    private static Logger logger = LoggerFactory.getLogger(ComponentServantProvider.class);    private static Map<String, Ice.Object> servantCache = new ConcurrentHashMap<String, Ice.Object>(200, 0.75F, 256);    public static Ice.Object getServantBean(String strToProxy) {        logger.info("查找代理类:"+strToProxy);        Ice.Object servant = (Ice.Object) servantCache.get(strToProxy);        if (servant == null) {            String itfc = buildInterfaceStr(strToProxy);            String impl = buildImplementStr(strToProxy);            logger.info("itfc"+itfc+";impl:"+impl);            if (logger.isDebugEnabled()) {                logger.debug("查找ice服务(servant对象), 使用标识(strToProxy):" + strToProxy);                logger.debug("使用ice服务接口类[" + itfc + "]创建服务.");//demo.Zan                logger.debug("使用ice服务实现类[" + impl + "]提供服务.");//demo.impl.ZanImpl            }            servant = loadServantInstance(itfc, impl);            servantCache.put(strToProxy, servant);        }        return servant;    }    private static String buildImplementStr(String strToProxy) {        int prxIndex = strToProxy.lastIndexOf("Prx");        if (prxIndex <= 0) {            throw new RuntimeException("非法请求");        }        int lastPointIndex = strToProxy.lastIndexOf(".");        String lastSub = strToProxy.substring(lastPointIndex + 1);        if (!lastSub.endsWith("Prx")) {            throw new RuntimeException("非法请求");        }        String shortClazzName = lastSub.substring(0, lastSub.length() - 3);        StringBuilder sb = new StringBuilder(strToProxy.length() + 10);        sb.append(strToProxy.substring(0, lastPointIndex));        sb.append(".impl.").append(shortClazzName).append("Impl");        String impl = sb.toString();        return impl;    }    private static String buildInterfaceStr(String strToProxy) {        int prxIndex = strToProxy.lastIndexOf("Prx");        String itfc = strToProxy.substring(0, prxIndex);        return itfc;    }    private static Ice.Object loadServantInstance(String itfc, String impl) {        try {            Class clazz = Class.forName(impl);            Object target = clazz.newInstance();            return (Ice.Object) target;        } catch (Throwable thr) {            logger.error("未找到实例");        }        return null;    }}

方法一是简单的应用,每次只能公共化一个接口,不适宜框架级应用,方法二初始化无须具体服务对象,更适应框架级应用.
实际项目中,往往只对外提供一个方法,如第二个ice文件,只对外提供string doRequest(string jsonStr);实现类在impl包下, 把具体的请求类、方法、参数通过一定的形式转化为json字符串传过来,一个后端初始框架就完成了。往外引申很大,这里就不详细叙说了。

原创粉丝点击