最近工作中使用了thrift,作为小白,摘录和总结了一些thrift基本语法及使用实例,仅做记录
Thrift类型系统包括预定义基本类型,用户自定义结构体,容器类型,异常和服务定义
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)
List
Set
Map
容器中的元素类型可以是除service以外的任何合法的thrift类型,包括结构体和异常类型
规定:
1.编译器默认从0开始赋值
2.可以赋予某个常量某个整数
3.允许常量是十六进制整数
4.末尾无分号或逗号
5.给常量赋缺省值时,使用常量的全称
6.Thrift不支持枚举类嵌套,枚举常量必须是32位的正整数
例:
enum MyEnum {
PEAR,
APPLE = 3,
BANANA = 0xa,
MANGO
}
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;
}
异常在语法和功能上类似于结构体,只是异常使用关键字exception而不是struct关键字来声明。但它在语义上不同于结构体—当定义一个RPC服务时,开发者可能需要声明一个远程方法抛出一个异常。
Thrift中服务定义的方式和语法等同于面向对象语言中定义接口。Thrift编译器会产生实现接口的client和server桩。具体有以下规定:
1.函数定义可以使用逗号或分号标识结束
2.参数可以是基本类型或者结构体,但参数只能是只读的(const),不可以作为返回值
3.返回值可以是基本类型或者结构体
4.返回值可以是void
服务的定义在后文的实例中可以找到。
Thrift支持C/C++风格的typedef:
typedef i32 MyInteger
typedef Student STDNT
注意末尾无逗号
Thrift支持shell注释风格、C/C++语言中的单行或多行注释风格,不再赘述。
Thrift中的命名空间同C++中的namespace类似,它提供了一种组织(隔离)代码的方式。因为每种语言均有自己的命名空间定义方式,thrift允许开发者针对特定语言定义namespace:
namespace cpp com.example.project
最近工作中使用了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);
}
打开Linux(centos)终端,通过命令进入DataInfo.thrift所在文件夹下,执行以下命令:
thrift -r --gen cpp DataInfo.thrift
生成的文件保存在该目录下的gen-cpp文件夹下。
注意,在****.skeleton.cpp文件中,有默认的服务启动接口,需要修改的童鞋可以视个人需求修改。
#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;
}
对服务中的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