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

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介:

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/archive/2012/12/17/2822231.html,如需转载请自行联系原作者

相关文章
|
4月前
|
前端开发 中间件 索引
Django入门到放弃之中间件
Django入门到放弃之中间件
|
4月前
|
存储 中间件 PHP
Python编程入门:从零到一的代码实践深入理解 PHP 中的中间件模式
【8月更文挑战第28天】本文旨在通过浅显易懂的方式,向初学者介绍Python编程的基础知识,并结合具体代码示例,带领读者一步步实现从零基础到能够独立编写简单程序的转变。文章将围绕Python语言的核心概念进行讲解,并通过实例展示如何应用这些概念解决实际问题。无论你是编程新手还是希望扩展技能的专业人士,这篇文章都将为你打开编程世界的大门。 【8月更文挑战第28天】在PHP的世界中,设计模式是构建可维护和可扩展软件的重要工具。本文将通过浅显易懂的语言和生动的比喻,带领读者深入理解中间件模式如何在PHP应用中发挥魔力,实现请求处理的高效管理。我们将一步步揭开中间件的神秘面纱,从它的定义、工作原理到
|
5月前
|
运维 中间件 PHP
深入理解PHP中的中间件模式自动化运维之脚本编程实践##
【7月更文挑战第31天】在PHP开发中,中间件模式是一种强大的设计模式,它允许开发者在请求处理流程中注入自定义的处理逻辑。本文将通过实际代码示例来探讨如何在PHP项目中实现和使用中间件,以及这种模式如何提升应用程序的可维护性和扩展性。 【7月更文挑战第31天】 在现代IT运维管理中,自动化不再是可选项,而是提高生产效率、确保服务质量的必需品。本文将通过Python脚本编程的角度,探讨如何利用代码简化日常运维任务,提升工作效率。我们将从实际案例出发,逐步剖析自动化脚本的设计思路、实现过程及其带来的益处。 ##
37 0
|
6月前
|
设计模式 Java 中间件
深入Java中间件:编程设计精粹
深入Java中间件:编程设计精粹
97 2
|
资源调度 JavaScript 前端开发
Redux异步解决方案 1. Redux-Thunk中间件
Redux异步解决方案 1. Redux-Thunk中间件
106 0
|
存储 缓存 Java
详解Zookeeper(铲屎官)在众多中间件的应用和在Spring Boot业务系统中实现分布式锁和注册中心解决方案
`ZooKeeper `是一个**开放源码的分布式协调服务**,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。 分布式应用程序可以基于` Zookeeper` 实现诸如**数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列**等功能。
23141 11
详解Zookeeper(铲屎官)在众多中间件的应用和在Spring Boot业务系统中实现分布式锁和注册中心解决方案
|
7月前
|
资源调度 JavaScript 前端开发
Redux 异步解决方案2. Redux-Saga中间件
Redux 异步解决方案2. Redux-Saga中间件
31 0
|
7月前
|
资源调度 JavaScript 前端开发
Redux异步解决方案 1. Redux-Thunk中间件
Redux异步解决方案 1. Redux-Thunk中间件
53 0
|
SQL 关系型数据库 中间件
postgresql从入门到精通 - 第35讲:中间件PgBouncer部署
postgresql技术大讲堂,从入门到精通 - 第35讲:中间件PgBouncer部署
290 1
|
消息中间件 存储 Java
消息中间件第一讲:RocketMQ从入门到精通
消息中间件第一讲:RocketMQ从入门到精通
534 2