Thrift语法简介与实例(c++)

最近工作中使用了thrift,作为小白,摘录和总结了一些thrift基本语法及使用实例,仅做记录

1 类型

Thrift类型系统包括预定义基本类型,用户自定义结构体,容器类型,异常和服务定义

1.1 基本类型

bool: 布尔类型,占一个字节

byte: 有符号字节   //对应C++  char

i16:16位有符号整型   //对应C++  short

i32:32位有符号整型   //对应C++  int

i64:64位有符号整型   //对应C++  long

double:64位浮点数   //对应C++  double

string:未知编码或者二进制的字符串   //对应C++  string

注意:thrift不支持无符号整形,因为很多目标语言不存在无符号整形(比如java)

1.2 容器

List:一系列t1类型的元素组成的有序列表,元素可以重复,对应c++中vector

Set:一些t1类型的元素组成的无序集合,元素唯一不重复,对应c++中set

Map:key/value对,key唯一,对应c++中map

容器中的元素类型可以是除service以外的任何合法的thrift类型,包括结构体和异常类型

1.3 枚举

规定:

1.编译器默认从0开始赋值

2.可以赋予某个常量某个整数 

3.允许常量是十六进制整数 

4.末尾无分号或逗号

5.给常量赋缺省值时,使用常量的全称

6.Thrift不支持枚举类嵌套,枚举常量必须是32位的正整数

例:

enum MyEnum { 
PEAR,       
APPLE = 3, 
BANANA = 0xa,  
MANGO
}  

1.4 结构体

1.struct不能继承,但是可以嵌套,不能嵌套自己。

2.其成员都是有明确类型

3.成员是被正整数编号过的,其中的编号使不能重复的,这个是为了在传输过程中编码使用。

4.成员分割符可以是逗号(,)或是分号(;),而且可以混用

5.字段会有optional和required之分和protobuf一样,但是如果不指定则为无类型–可以不填充该值,但是在序列化传输的时候也会序列化进去,optional是不填充则不序列化,required是必须填充也必须序列化。

6.每个字段可以设置默认值

7.同一文件可以定义多个struct,也可以定义在不同的文件,进行include引入。

例:

include "teacher.thrift" //另一thrift文件,内含一个结构体struct Teacher

struct Student{
    required i32 Id;                  
    optional string name;                            
    optional string language = "Chinese"; 
}
struct Class{                           
    required i16 Id;
    required List vecStudent;
    required teacher.Teacher myTeacher;
}

1.5 异常

异常在语法和功能上类似于结构体,只是异常使用关键字exception而不是struct关键字来声明。但它在语义上不同于结构体—当定义一个RPC服务时,开发者可能需要声明一个远程方法抛出一个异常。

1.6 服务

Thrift中服务定义的方式和语法等同于面向对象语言中定义接口。Thrift编译器会产生实现接口的clientserver桩。具体有以下规定:

1.函数定义可以使用逗号或分号标识结束

2.参数可以是基本类型或者结构体,但参数只能是只读的(const),不可以作为返回值

3.返回值可以是基本类型或者结构体

4.返回值可以是void

服务的定义在后文的实例中可以找到。

1.7 类型定义

Thrift支持C/C++风格的typedef:

typedef i32 MyInteger 
typedef Student STDNT

注意末尾无逗号

2 注释

Thrift支持shell注释风格、C/C++语言中的单行或多行注释风格,不再赘述。

3 命名空间和常量

Thrift中的命名空间同C++中的namespace类似,它提供了一种组织(隔离)代码的方式。因为每种语言均有自己的命名空间定义方式,thrift允许开发者针对特定语言定义namespace:

namespace cpp com.example.project

4 一个简单的例子

最近工作中使用了thrift, 此处举一个简单的例子。

4.1 下载并安装thrift

略。

4.2 编写thrift文件,定义结构体,接口及异常

以下是我使用的thrift文件DataInfo.thrift:

struct GroupInfo{
1: string groupId;
2: i16 state;
}

struct DataInfo{
1: list vecGroupInfo;
}

service Data_Service{
string Ping(1: string teststr);
DataInfo GetData(1: i32 DataId);
}

4.3 生成接口代码

打开Linux(centos)终端,通过命令进入DataInfo.thrift所在文件夹下,执行以下命令:

thrift -r --gen cpp DataInfo.thrift

生成的文件保存在该目录下的gen-cpp文件夹下。

注意,在****.skeleton.cpp文件中,有默认的服务启动接口,需要修改的童鞋可以视个人需求修改。

4.4 编写客户端代码

#include "Data_Service.h" //你的服务头文件
#include 
#include 
#include 
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using boost::shared_ptr;

int main(int argc, char **argv) {
    boost::shared_ptr socket(new TSocket("localhost", 9090)); //注意此处的ip和端口
    boost::shared_ptr transport(new TBufferedTransport(socket));
    boost::shared_ptr protocol(new TBinaryProtocol(transport));
    transport->open();

    // 操作代码

    transport->close();
    return 0;
}

4.5 测试服务及客户端

对服务中的Ping和GetData方法进行简单的实现,在本地编译器中先启动服务工程,然后启动客户端工程,即可对其进行测试。

参考博客:

https://www.cnblogs.com/yuananyun/p/5186430.html

https://blog.csdn.net/u011642663/article/details/56015576

https://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html

https://blog.csdn.net/csfreebird/article/details/50319035

https://blog.csdn.net/byxdaz/article/details/74479671

你可能感兴趣的:(Thrift,C++)