ICE的应用

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字符串传过来,一个后端初始框架就完成了。往外引申很大,这里就不详细叙说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值