安装0.9.0版本
官方要求
- g++ 4.2
- boost 1.53.0
- autoconf 2.65
- automake 1.13
- libtool 1.5.24
安装步骤
- sudo yum -y install libevent-devel zlib-devel openssl-devel
- sudo yum -y groupinstall “Development Tools”
- sudo yum install gcc gcc-c++ bzip2 bzip2-devel bzip2-libs python-devel -y
- wget http://ftp.gnu.org/gnu/bison/bison-2.5.1.tar.gz
tar xvf bison-2.5.1.tar.gz
cd bison-2.5.1
./configure --prefix=/usr
make
sudo make install - wget http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz
tar xvf automake-1.14.tar.gz
cd automake-1.14
./configure --prefix=/usr
make
sudo make install - wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar xvf autoconf-2.69.tar.gz
cd autoconf-2.69
./configure --prefix=/usr
make
sudo make instal - wget http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.tar.gz
tar xvf boost_1_55_0.tar.gz
cd boost_1_55_0
./bootstrap.sh --prefix=/usr
sudo ./b2 install - wget http://archive.apache.org/dist/thrift/0.9.0/thrift-0.9.0.tar.gz
tar -xvzf thrift-0.9.0.tar.gz
cd thrift-0.9.0
./bootstrap.sh
./configure --prefix=/usr
make
make install
thrift基本类型
bool 布尔型,1个字节
byte 有符号整数,1个字节
i16 有符号16位整型
i32 有符号32位整型
i64 有符号64位整型
double 64位浮点数值
string 字符串类型
binary 二进制数据类型(字节数组)
list<t> 单类型有序列表,允许有重复元素
set<t> 单类型无需集合,不允许有重复元素
map<t1,t2> (key:value)
命名空间
namespace cpp Test
使用了上面语法后,该 .thrift文件下所用的内容都处于上面的命名空间中
类型别名
typedef i32 MyInter
跟 c/c++用法一致
常量
默认的在thrift全局内定义的基础变量都是常量,需要用 const修饰否则报错,对于map我们初始化,thrift真正的帮我们初始化了。但是对于list与set,我们虽然初始化了,但是并没有什么毛用对c++来说,thrift并不会帮我们初始化,但是我们还必须初始化。
const i32 CIntNum = 10000
const map<string , string > MyMap = {'hello':'world','cat':'whitecat'}
struct
- 结构体则是一个复杂的数据类型。它由域组成,每个域会对应一个整数标识符,
每个域的格式为:一个冒号,一个类型,一个域名称和一个(非必填的)默认值。
每个域都可以设置为optional或required来表示是否为必填域,以便thrift决定是否
在数据传输时要包含这个域。不指定时,默认为required,每个成员用 , 或者 ; 隔开。
如果设置为required 则我们可以直接通过访问结构体成员来赋值填充,如果是optional
的话,我们每个字段都需要通过相应接口来赋值填充 或者 通过__isset.typename = true 这种
方式置位True然后还是通过直接访问成员来填充 。如果不通过这俩个方式填充的话,那么
我们填充的数据就不会被发送到对端。 - 对于required 字段的内容,如果我们没有设置这些字段,thrift 会构造默认的内容然后发送到对端。如果是 optional 的字段,必须通过调用 相应接口 或者 设置 __isset标志,否则即使设置了这些字段也不会传输到对端。对于 required 的理解可以理解为 thrift 必须要传输这个字段, optional 理解为 thrift 可选择的传输这个字段。
- 如果不设置选项字段,也就是使用默认的,那么它也是有个 isset.field 的变量的,但是这个变量没用,即使设置为false,thrift也会把数据发送到对端。所以默认的效果跟required一样,但是required 没有isset.field字段,并且 required 字段设置后,当thrift底层读取 required字段的时候,它必须要读取到相应字段,如果没有则抛出异常。(默认 我们不设置required字段的话,发送端也会发送一个默认的required的值,这里对于读取的异常判断,我觉得可以理解为 thrift 序列化的结果中,thrift在解析的时候,必须要解析到 required的相应字段否则抛出异常,觉得这个是为了thrift 先后兼容时做的一个措施,因为thrift可以向后兼容,所以老版本代码照样可以解析新版本thrift的数据,如果新版本把required字段去掉了,发给老版本代码,这里required就会异常判断,然后抛出异常了)
- 对于默认字段的读取逻辑,Server/Client 读取默认的thrift数据,只要相应字段的类型对了,他就把相应字段_isset 置为 true。发送逻辑不会根据isset的标志(真或者假)去判别是否发送。
struct work {
1: optional i32 num1 = 0,
2: i16 num2; //默认required
3: optional string comment,
4. required string required_arg;
}
enum
在struct 定义枚举成员时候必须初始化,否则默认初始化为0会有隐藏bug!!!
test.thrift
//这个就会在全局作用域内生成一个相应的enum类型
enum Operator {
ADD=1,
SUB,
MUL,
DIV
}
struct work {
1:Operator op = Operator.ADD
}
Service 通信服务
这个就是thrift 的主逻辑了,里面可以定义通信的函数
#include "shared.thrift"
service Test extends shared.SharedService // 可以继承其他文件的方法
{
void TestPrint(),
i32 add(1:i32 num1,2:i32 num2),
i32 calculate(1:i32 id , 2:work w) throws(1:Invalidexp Iexp),
oneway void call()
}
oneway 只能修饰返回值为void 的函数,它表示这个函数以异步的方式调用
异常
这个可以定义在函数之后,方便函数在处理错误的时候抛出异常
exception Invalidexp {
1:i32 what ,
2:string why
}