Slice介绍


        为了开发多语言支持的RPC服务,需要一种中立的新语言来定义这个服务接口,以便各个编程语言能够准确无误地理解和翻译接口,为此Ice设计了Slice语言。Ice开发的第一步就是学习Slice语法,并掌握实际项目开发中所必须的一些技巧。

        Slice定义的基本数据类型:

Type

Range of Mapped Type

Size of Mapped Type

bool

false or true

≥ 1bit

byte

-128-127 or 0-255 a

≥ 8 bits

short

-2 15 to 2 15 -1

≥ 16 bits

int

-2 31 to 2 31 -1

≥ 32 bits

long

-2 63 to 2 63 -1

≥ 64 bits

float

IEEE single-precision

≥ 32 bits

double

IEEE double-precision

≥ 64 bits

string

All Unicode characters, excluding 
the character with all bits zero.

Variable-length

其他类型

Type

Range of Mapped Type

Size of Mapped Type

Ice::ByteSeq

二进制数组


说明:
    由于byte在Java里是无符号的,范围是-128~127,因此不建议将byte用作数值参数,而只用作原始字节类型传递二进制数据。
    时间类型可以使用long表示自1970年以来的毫秒数。
    string长度也是有限的,太长可能导致内存溢出。比如涉及文件传输这样的接口,不宜用字符串一次性传递完文件内容,而应该分批分段传递内容。
    除了bool和string其他都和Java一样。

除了基本数据类型,还定义了复合数据类型:

        

        注意:struct不能嵌套struct,但是可以引用struct。struct属性可以设置默认值。strut引用实体的时候变量名和类型不能一样。

例子:
定义常量:
const bool IsSuccess = true;
枚举使用:
enum Fruit { Apple, Pear , Orange}; //enum类型其实等价于int
const Fruit FavoriteFruit = Apple;

定义一个接口:使用关键字interface 
struct TimeOfDay{
    short hour;
    short minute;
    short second;
}
interface Clock{
    TimeOfDay getTime();
    void setTime(TimeOfDay time);
}

        支持类似java的Out Parameter 模式,传入一个map或者javabean在方法里面修改,然后方法结束以后可以修改成功。在参数新增out修饰符,即变为出参;(C#也是这样,Java不用修饰符即可)
        void changeSleepPeriod(TimeOfDay startTime, out TimeOfDay prevStartTime)

        高级技巧:在接口方法上增加Idempotent关键字,表示该方法是幂等的,即调用1次和调用2次其结果是一样的,比如常见的查询操作基本上都是幂等的,而update和create等方法则不是,若一个方法是幂等的,则增加Idempotent修饰后,可以让Ice更好的实现“自动恢复的机制”,即在某个Ice Object调用失败的情况下,无法区分是否已经调用过,但是在因为网络错误导致没有正确返回结果的情况下,Ice会再次调用有Idempotent修饰的方法,透明恢复故障,而在客户端看来则调用正常,没有感觉到Ice做了自动故障恢复的操作。

异常也是可以定义的,语法如下:
exception Error {} ; // 空异常是允许的
exception RangeError{
    TimeOfDay errorTime;
    TimeOfDay minTime;
    TimeOfDay maxTime;
};

        多个模块的接口引用共同的数据对象类型的问题,可以将公用的数据对象定义放在一个Slice文件中,如common.sclice,然后其他接口通过关键字#include引用这个文件:
        #include common.slice

第一个程序Hello World


1. 新建项目test_ice,右击Ice Builder→Add Ice Builder

2. 定义接口
    在slice目录右击New File :myservice.ice,
1
2
3
4
5
6
7
[["java:package:com.my.demo"]]
module demo{   //module demo模块名,module和Java的Package是对应的,当前默认package是demo
                //如果需要生成和Java对应的package的话,在module上面新增[["java:package:com.my.demo"]]即可,包名为com.my.demo.demo
    interface MyService{
        string hello();
    };
};
Ctrl+s 会自己在generated目录下的com.my.demo.demo下生成ice的java源代码

3. 服务端实现
    1)在src的service包下新建服务类MyServiceImp继承_MyServiceDisp,并实现Slice定义的接口,实现具体的业务逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package service;
 
import com.my.demo.demo._MyServiceDisp;
import Ice.Current;
 
public class MyServiceImpl extends _MyServiceDisp {
 
    private static final long serialVersionUID = 7114601588161119171L;
 
    @Override
    public String hello(Current __current) {
        return "Hello Jerome"; //只是简单的返回
    }
 
}

    2)新建启动服务端的代码MyServiceStarter   
        接下来我们需要新建一个MyServiceImpl实例,这就是之前提到的Servant对象,然后用一个唯一的ID(Ice Object Identity)将其关联到一个Ice Object对象上(ASM过程),最后绑定到一个Object Adapter上,然后我们的客户端(Proxy)就可以通过Object Adapter提供的Endpoint通信端口与这个Servant进行远程通信了。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package service;
 
public class MyServiceStarter {
    public static void main(String[] args) {
        int status = 0;
        Ice.Communicator ic = null;
        try {
            // 初始化Communicator对象,args可以传一些初始化参数,如连接超时,初始化客户端连接池的数量等
            ic = Ice.Util.initialize(args);
            // 创建名为MyServiceAdapter的ObjectAdapter,使用缺省的通信协议(TCP/IP端口为10001的请求)
            Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("MyServiceAdapter""default -p 10001");
            // 实例化一个MyService服务对象(Servant)
            MyServiceImpl servant = new MyServiceImpl();
            // 将Servant增加到ObjectAdapter中,并将Servant关联到ID为MyService的Ice Object
            adapter.add(servant, Ice.Util.stringToIdentity("MyService"));
            // 激活ObjectAdapter
            adapter.activate();
            // 让服务在退出之前,一直持续对请求的监听
            System.out.println("server is started ... ");
            ic.waitForShutdown();
        catch (Exception e) {
            e.printStackTrace();
            status = 1;
        finally {
            if (ic != null) {
                ic.destroy();
            }
        }
        System.exit(status);
    }
}

    上述代码的Ice Communicator对象是负责处理网络通信实现RPC调用的,不管在客户端还是服务端都是Communicator这个对象在背后默默地完成无人关注的底层工作。(另外,网络通信的框架代码都是很复杂的,通常内含连接池和线程池,而这两种资源都是有限的资源,并且创建和释放都很耗时,所以要尽量复用这些对象(Communicator)而不是任性的New和Destroy。)

4. 客户端实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package client;
 
import com.my.demo.demo.MyServicePrx;
import com.my.demo.demo.MyServicePrxHelper;
 
public class MyClient {
    public static void main(String[] args) {
        int status = 0;
        Ice.Communicator ic = null;
        try {
            // 初始化通信容器
            ic = Ice.Util.initialize(args);
            // 传入远程服务单元的名称、网络协议、IP及端口,构造一个Proxy对象
            Ice.ObjectPrx base = ic.stringToProxy("MyService:default -p 10001");
            // 通过checkCast向下转型,获取MyService接口的远程,并同时检测根据传入的名称获取服务单元是否OnlineBook的代理接口
            MyServicePrx prxy = MyServicePrxHelper.checkedCast(base);
            if (prxy == null) {
                throw new Error("Invalid proxy");
            }
            // 调用服务方法
            String rt = prxy.hello();
            System.out.println(rt);
        catch (Exception e) {
            e.printStackTrace();
            status = 1;
        finally {
            if (ic != null) {
                ic.destroy();
            }
        }
        System.exit(status);
    }
}
    MyServicePrx prxy = MyServicePrxHelper.checkedCast(base);//将一个“通用”的Proxy对象转换成一个具体的Proxy对象,原理是“通用”的Proxy里面包括远程Ice Object的Endpoint地址,具体Proxy的Helper类只要用此地址调用一些远程对象,即可判断是否是自己代理的Object了,因此在MyServicePrxHelper.checkedCast的实现逻辑中,包括了一次远程调用的过程,如果确信不会张冠李戴则可以用uncheckedCast(base)方法转换,避免了一次通信过程,有性能上的优势。
    运行服务端程序MyServerStarter,然后客户端MyClient 访问即可。

5. Python客户端实现
    确保安装了Python环境。然后cmd运行pip install zeroc-ice 安装ice的包,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python
# **********************************************************************
#
# Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
#
# This copy of Ice is licensed to you under the terms described in the
# ICE_LICENSE file included in this distribution.
#
# **********************************************************************
 
import sys, traceback, Ice
 
Ice.loadSlice("D:\\Java\\workspace\\workspace-temp\\test_ice\\slice\\myservice.ice")
import demo
 
status = 0
ice = None
try:
    ic = Ice.initialize(sys.argv)
    base = ic.stringToProxy("MyService:default -p 10001")
    printer = demo.MyServicePrx.checkedCast(base)
    if not printer:
        raise RuntimeError("Invalid proxy")
 
    result = printer.hello()
    print result
except:
    traceback.print_exc()
    status = 1
 
if ic:
    # Clean up
    try:
        ic.destroy()
    except:
        traceback.print_exc()
        status = 1
 
sys.exit(status)


参考
        1.  《ZeroC Ice 权威指南》2.4


资料
        代码:链接:http://pan.baidu.com/s/1c1bkx8G 密码:j2xw
        所有slice数据类型的使用demo代码:链接:http://pan.baidu.com/s/1ntV2sDr 密码:jznd

Zeroc Ice Slice语言使用 HelloWorld的更多相关文章

  1. ICE:slice语言常识整理

    ICE:Slice语言(二)--源文件和词法规则:    文件命名    Slice的源文件以.ice为扩展名.   对于大小写不区分的系统(例如DOS),文件的扩展名可以大写,也可以小写,例如Cli ...

  2. ICE学习第三步-----Slice语言

    ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器 ...

  3. ZeroC ICE的远程调用框架 Slice如何帮助我们进行Ice异步编程(AMI,AMD)

    Slice最大的用处就是为我们使用Ice进行编程,代劳绝大部分的重复性代码,并提供一些帮助性的框架代码,如用于AMI和AMD方式进行异步编程的回调框架. 当Slice不为我们生成代码时,我们仍然可以按 ...

  4. ZeroC Ice 暂记

    摘自: http://weibo.com/p/1001603869896789339575 原文地址: http://www.oschina.net/question/865233_242146 吴治 ...

  5. ZEROC ICE 跨平台间程序调用 java版

    前言: 本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE. 最近一个项目涉及到java.python ...

  6. Zeroc Ice原理介绍

    Ice介绍         Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件.Ice是RPC通 ...

  7. Zeroc Ice开发环境搭建

    搭建Ice环境 1. Linux(推荐,更接近真实生产环境) 2. Windows(方便学习开发)     下载安装包:https://zeroc.com/downloads (百度网盘链接:http ...

  8. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

  9. 用Python开发Zeroc Ice应用

    Zeroc Ice简介   Zeroc ICE(Internet Communications Engine ,互联网通信引擎)是目前功能比较强大和完善的RPC框架,支持跨平台.跨语言调用.它非常灵活 ...

随机推荐

  1. Cloud TPU Demos(TensorFlow 云 TPU 样例代码)

    Cloud TPU Demos 这是一个Python脚本的集合,适合在开源TensorFlow和 Cloud TPU 上运行. 如果您想对模型做出任何修改或改进,请提交一个 PR ! https:// ...

  2. sqlserver 判断字段是否为空字符串或者null

    isnull(f.mzm,'')<>'' 不为null且不为‘’ not(f.mzm is null) 不为null

  3. 关于一些基础的Java问题的解答(三)

    11. HashMap和ConcurrentHashMap的区别   从JDK1.2起,就有了HashMap,正如上一个问题所提到的,HashMap与HashTable不同,不是线程安全的,因此多线程 ...

  4. IOI2016Day2. paint

    题目链接:http://uoj.ac/problem/238 题目大意: 有一个长度为n的黑白序列,告诉你所以k个极长连续黑段长度和顺序.有一些位置的颜色已知,需要判断剩下未知的位置哪些颜色 一定是白 ...

  5. jvm(四):垃圾回收

    垃圾回收我们主要从以下三个方面进行描述 垃圾对象的判断 目前判断对象为垃圾对象有两种方法:引用计数法,可达性分析法,目前普遍是的是可达性分析法 可达性分析法的实现原理: 定义gcroot一直往下找,如 ...

  6. 安利三款提升幸福感的chrome插件

    谷歌访问助手 chrome浏览器一直是各大码农推荐的比较好用的浏览器,速度快.插件多. 但是由于众所周知的原因导致了谷歌账号同步.扩展商店访问慢甚至打不开的情况. 谷歌访问助手就是用来解决此问题的. ...

  7. 利用Filter和拦截器,将用户信息动态传入Request方法

    前言: 在开发当中,经常会验证用户登录状态和获取用户信息.如果每次都手动调用用户信息查询接口,会非常的繁琐,而且代码冗余.为了提高开发效率,因此就有了今天这篇文章. 思路: 用户请求我们的方法会携带一 ...

  8. Django REST Framework 最佳实践

    Django REST framework 是一个强大且灵活的工具包,用以构建Web APIs. 为什么要使用REST framework? - 在线可视的API,对于赢得你的开发者们十分有用 - 验 ...

  9. Antlr v4入门教程和实例

    1 重逢ANTLR 最早知道ANTLR是当年学习Apache Derby数据库源码时,在看到SQL解析那一层时,第一次看到编译原理在实际项目中的应用,惊叹之余也只能望而却步.之前也根据网上一些资料尝试 ...

  10. Launcher3 HotSeat显示名称

    今天闲的无聊,研究了下launcher代码,看到Hotseat.java的时候,想起来以前有做过显示hotseat中应用名称,因为换了公司代码都没拿出来,就想在试着修改,看了很久发现无从下手,记得ho ...