• 【通信中间件】电信级解决方案中间件ICE编程入门指南


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    0.ICE介绍:ICE(Internet Communications Engine)是ZeroC提供的一款高性能的中间件,基于ICE可以实现电信级的解决方案。个人理解与COBRA貌似基本上是一个作用的东西,由于项目上要用到,早上简单实用了一下,还是很方便的。

    1.开发流程

    编写ICE接口文件=>选择开发语言,生成相关类和接口=>开发Server端=>开发Client端=>部署Server端=>运行Client

    2.安装:

    环境:Ubuntu 9.10

    $sudo apt-get install zeroc-*

    3.实例:编写一个名为shareiceserver 的模块,里面有一个名为Sonics的接口

    1)编写ICE文件:

    module shareiceserver {

        interface Sonics{
            int authenUser(string userID, string password);
            bool isOrdered(string userID, string appID);// SONICS查询某用户是否订购某业务:返回值bool
            bool checkBalanceByName(string userID, double balance);
            string getHomeSCSByUserID(string userID);//SONICS查询某用户归属SCS信息:返回值
               };

    }; //shareiceserver

    在这个模块中,我们定义了一个接口,请注意这个接口与Java中的接口并不是一个概念,在后边自动生成代码时会生成一系列类和接口。

    将这个文件保存为shareiceserver.ice

    2)选择开发语言:

    我们在此选择Java作为C-S两端的语言,当然,由于ICE的封装,在两端分别使用哪种语言其实并没有关系。接着,我们将这个接口文件生成Java proxies 和skeletons,这两者的具体概念请参看我的Blog的另一篇文字:《分布计算环境学习笔记2——分布式系统中的面向对象技术》,其中关于IDL语言的对应关系与此道理相同。

    生成接口和类文件

    slice2java shareiceserver.ice

    此时会产生一个叫做shareiceserver的文件夹:

    sam@sam-desktop:~/ICE/shareiceserver$ ls
    _SonicsDelD.java  _SonicsDelM.java  SonicsHolder.java  _SonicsOperations.java    SonicsPrxHelper.java  SonicsPrx.java
    _SonicsDel.java   _SonicsDisp.java  Sonics.java        _SonicsOperationsNC.java  SonicsPrxHolder.java

    3)开发Server端(传统方法)

    a.添加定义的方法的具体实现:SonicsI.java

    public class SonicsI extends shareiceserver._SonicsDisp{
            public int authenUser(String userID, String password, Ice.Current current)
            {
                    return 0;
            }

            public boolean checkBalanceByName(String userID, double balance, Ice.Current current)
            {
                    return true;
            }

            public String getHomeSCSByUserID(String userID ,Ice.Current current)
            {              

                    return userID+":192.168.0.1";

            }

            public boolean isOrdered(String userID, String appID, Ice.Current current)
            {
                    return true;
            }
    }

    继承_SonicsDisp创建servant类SonicsI(一般我们在接口的名字后边加上I表示servant类),_SonicsDisp是自动生成的,这是个抽象类,包含了我们要实现的方法的原型(只是每一个方法都加入了一个Ice.Current类型的参数)。我们这里只是示意性的对方法进行了实现,没有什么具体的逻辑。

    .b.编写Server端主程序代码:Server.java

    public class Server {
        public static void
        main(String[] args)
        {
            int status = 0;
            Ice.Communicator ic = null;
            try {
                ic = Ice.Util.initialize(args);//初始化Ice,返回一个Ice::Communicator引用作为Ice的运行操作句柄。
                Ice.ObjectAdapter adapter//在此Ice环境下创建一个对象适配器(名为SimpleSonics),default为使用默认协议TCP/IP,并使用端口10000。初始化至此完成。
                    = ic.createObjectAdapterWithEndpoints(
                        "SimpleSonics", "default -p 10000");
                Ice.Object object = new SonicsI();//创建一个servant实例。
                adapter.add(
                        object,
                        Ice.Util.stringToIdentity("SimpleSonics"));//将这个servant实例加入对象适配器,并且指明名称。
                adapter.activate();//激活适配器
                ic.waitForShutdown();//这个调用将该线程挂起直到Server终止。在这里,我们简单使用命令行终止的方式。
            } catch (Ice.LocalException e) {
                e.printStackTrace();
                status = 1;
            } catch (Exception e) {
                System.err.println(e.getMessage());
                status = 1;
            }
            if (ic != null) {
                // Clean up
                //
                try {
                    ic.destroy();//在程序退出之前要对Ice整个环境进行销毁。
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                    status = 1;
                }
            }
            System.exit(status);
        }
    }

    在编写Server端程序时,我们要对ICE和以及程序逻辑运行时可能抛出的异常做处理,然后再注册启动Server端。

    编译:(在ubuntu环境下Ice.jar的位置如下,其他环境需要修改)

    $mkdir classes

    $javac Server.java SonicsI.java shareiceserver/*.java -classpath /usr/share/java/Ice.jar -d classes

    4)编写Client端主程序代码:Client.java

    public class Client {
        public static void
        main(String[] args)
        {
            int status = 0;
            Ice.Communicator ic = null;
            try {
                ic = Ice.Util.initialize(args);//初始化Ice环境
                Ice.ObjectPrx base = ic.stringToProxy(//添加一个代理,设定名字、协议、端口。返回接口与类的继承树的根部
                       "SimpleSonics:default -p 10000");
               shareiceserver.SonicsPrx sonicser
                    =shareiceserver.SonicsPrxHelper.checkedCast(base);//沿着这个继承树寻找Sonics
                if (sonicser== null)//若无法找到则返回null,至此准备工作完成。
                    throw new Error("Invalid proxy");

                System.out.println(sonicser.getHomeSCSByUserID("001"));//具体方法调用
            } catch (Ice.LocalException e) {
                e.printStackTrace();
                status = 1;
            } catch (Exception e) {
                System.err.println(e.getMessage());
                status = 1;
            }
            if (ic != null) {
                // Clean up
                //
                try {
                    ic.destroy();//销毁Ice环境
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                    status = 1;
                }
            }
            System.exit(status);
        }
    }

    编译:

    javac Client.java shareiceserver/*.java -classpath /usr/share/java/Ice.jar -d classes

    5)部署运行:

    环境配置:(否则出现NoClassDefFoundError: Ice/LocalException异常)

    export CLASSPATH=$CLASSPATH:./classes:/usr/share/java/Ice.jar

    Server端运行:

    ~/ICE/classes$ java Server &

    Client端运行:

    ~/ICE/classes$ java Client

    运行结果:

    001:192.168.0.1

    4.使用Ice.Application创建Server和Client端

    在官方文档中,推荐在只创建一个communicator时使用Ice.Application类进行程序编写(http://www.zeroc.com/doc/Ice-3.2b/manual/Javas.13.3.html)。

    Server端:Server1.java

    public class Server1 extends Ice.Application {
        public int
        run(String[] args)
        {
            Ice.Communicator ic = communicator();
             Ice.ObjectAdapter adapter
                    = ic.createObjectAdapterWithEndpoints(
                        "SimpleSonics", "default -p 10000");
                Ice.Object object = new SonicsI();
                adapter.add(
                        object,
                        Ice.Util.stringToIdentity("SimpleSonics"));
                adapter.activate();
                ic.waitForShutdown();

            return 0;
        }

        public static void
        main(String[] args)
        {
            Server1 app = new Server1();
            int status = app.main("Server1", args);
            System.exit(status);
        }
    }

    Client端:Client1.java

    public class Client1 extends Ice.Application {
        public int
        run(String[] args)
        {
            Ice.Communicator ic = Ice.Util.initialize(args);
            Ice.ObjectPrx base = ic.stringToProxy(
                "SimpleSonics:default -p 10000");
            shareiceserver.SonicsPrx sonicser
                =shareiceserver.SonicsPrxHelper.checkedCast(base);
            if (sonicser== null)
                throw new Error("Invalid proxy");

            System.out.println(sonicser.getHomeSCSByUserID("001"));

            return 0;
        }

        public static void
        main(String[] args)
        {
            Client1 app = new Client1();
            int status = app.main("Client1", args);
            System.exit(status);
        }
    }

    使用这个类的好处是程序清晰,并且自动在其中提供了信号处理、配置等功能。编译方法与上相同。

    5.关闭信号的捕捉

    在Ice.Application中,在JVM关闭之前程序默认调用destroyOnInterrupt这个回调函数完成一些clean和hint的工作:

    if(interrupted())
                   System.err.println(appName()+ ": terminating");
           return 0;

    但是这个默认的回调函数在主程序阻塞时(比如主程序接收键盘输入时)不会被调用,为了克服这一特点,我们可以自己注册一个回调函数:

    public class Server extends Ice.Application {
        class ShutdownHook extends Thread {
            public voidrun()
            {
                try
                {
                    communicator().destroy();
                }
                catch(Ice.LocalException ex)
                {
                    ex.printStackTrace();
                }
            }
        }

        public intrun(String[] args)
        {
            setInterruptHook(new ShutdownHook());

            // ...
        }
    }

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

  • 相关阅读:
    [置顶] Android中定时器的3种实现方法
    [置顶] Android代码应用程序通过WakeLock保持后台唤醒状态
    [置顶] 当爱情遇上互联网
    [置顶] Android咨询阿米巴基金合伙人李治国:我为什么投资快的打车?
    [置顶] Android问题Getting Android Sensor Events While The Screen is Off
    静态SQL和动态SQL
    IBM Data Studio使用对象创建的双引号/大小写问题以及表/列重命名
    DB2数据库查询过程(Query Processing)统计信息与过滤因子(Statistics and Filter Factors)
    DB2数据库查询过程(Query Processing)概述
    DB2数据库查询过程(Query Processing)表扫描与I/O(Table Scan and I/O)
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2822231.html
Copyright © 2020-2023  润新知