本文中将介绍thrift产生各种语言代码的方式,转载自:http://dongxicheng.org/search-engine/thrift-guide/点击打开链接
thrift的网络栈如下所示:
1、transport
transport层提供了一个简单的网络读写抽象层。这使得thrift底层的transport从系统其他部分(如:序列化/反序列化)解耦。以下是一些Transport接口提供的方法:
1)open
2)close
3)read
4)write
5)flush
除了以上几个接口,thrift使用ServerTransport接口接受或者创建原始transport对象。正如名字暗示的那样,ServerTransport用在serve端,为到来的连接创建Transport对象。主要接口有:
1)open
2)listen
3)accept
4)close
2、protocol层
Protocol抽象层定义了一种将内存中数据结构映射成可传输格式的机制。协议的主要作是用于制定数据类型进行编码和解码,这是传输的第一步,然后我们就按照一定的规则将经过编码的数据封装到报文中进行传输,而上层只需要按照固定的解析格式来解析数据就行了。
Protocol接口的定义如下:
writeMessageBegin(name,type,seq)
writeMessageEnd()
writeStructBegin(name)
writeStructEnd()
writeFieldBegin(name,type,id)
writeFieldEnd()
writeMapBegin(ktype,vtype,size)
writeMapEnd()
writeListBegin(etype,size)
writeListEnd()
writeSetBegin(etype,size)
writeSetEnd()
writeBool(bool)
writeByte(byte)
writeI16(i16)
writeI32(i32)
writeI64(i64)
writeDouble(double)
writeString(string)
name,type,seq = readMessageBegin()
readMessageEnd()
name = readStructBegin()
readStructEnd()
name,type,id = readFieldBegin()
readFieldEnd()
k,v,size = readMapBegin()
readMapEnd()
etype,size = readListBegin()
readListEnd()
etype,size = readSetBegin()
readSetEnd()
bool = readBool()
byte = readByte()
i16 = readI16()
i32 = readI32()
i64 = readI64()
double = readDouble()
string = readString()
下面列举thrift支持的解析格式:
1)json
2)xml
3)纯文本
4)二进制
3、processor层
Processor封装了从输入数据流中读数据和向输出数据流中写数据的操作。读写数据流用Processor对象表示。Processor的结构体非常简单:
interfaceTProcessor {
bool process(TProtocol in,TProcol out)theows TException
}
与服务相关的processor实现由编译器产生。processor主要工作流程如下:从连接中读取数据(使用输入protocol),将处理授权给handler(有用户实现),最后将结果写到连接上(使用输出protocol)。
4、server
server将以上所有特性集成在一起:
(1)创建一个transport对象
(2)为transport对象创建输入输出protocol
(3)基于输入输出protocol创建processor
(4)等待连接请求并将之交给processor处理
5、应用举例
下面,我们讨论thrift文件产生的特定语言代码。下面给出thrift文件描述:
namespace cpp thrift.example
namespace java thrift.example
enum TweetType {
TWEET,
RETWEET = 2,
DM = 0xa,
REPLY
}
struct Location {
1:required double latitude;
2:required double longitude;
}
struct Tweet {
1:required i32 userId;
2:required string userName;
3:required string text;
4:optional Location loc;
5:optional TweetType = TweetType.TWEET;
16:optional string language = "english";
}
typedef list<Tweet>TweetList
struct TweetSearchResult {
1:TweerList tweets;
}
const i32 MAX_RESULT = 100;
service Twitter {
void ping(),
bool postTweet(1:Tweet tweet);
TweetSearchResult searchTweets(1:string query);
oneway void zip()
}
(1)Java语言
(a)产生的文件
一个单独的文件(Constants.java)包含所有的常量定义。
每个结构体、枚举或者服务各占一个文件
$tree gen-java
'-thrift
'-example
|-Constants.java
|-Location.java
|-Tweet.java
|-TweetSearchResult.java
|-TweetType.java
'-Twitter.java
(b)类型
thrift将各种基本类型和容器类型映射成.java类型:
bool:boolean
byte:byte
i16:short
i32:int
i64:long
double:double
string:String
list<t1>:List<t1>
set<t1>:Set<t1>
map<t1,t2>:Map<t1,t2>
(c)typedef
Java不支持typedef,它只使用原始类型,如,在上面的例子中,产生的代码中,TweetSearchResult会被还原为list<Tweet>tweets
(d)Enum
thrift直接将枚举类型映射成.java类型。用户可以使用getValue方法获取枚举常量的值。此外,编译器会产生一个findByValue方法获取枚举对应的数值。
(e)常量
thrift把所有的常量放在一个叫 Constants的public类中,每个常量修饰符是public static final。
(2)C++语言
(a)产生的文件
所有变量均存放在一个.cpp/.h文件
所有的类型定义(枚举或者结构体)存放到另一个.cpp/.h文件对中
每一个service有自己的.cpp/.h文件
$tree gen-cpp
|-example_constants.cpp
|-example_constants.h
|-example_types.cpp
|-example_types.h
|-Twitter.cpp
|-Twitter.h
'-Twitter_server.skeleton.cpp
其他语言
Python,Ruby,Javascript等
本文转载自董的博客http://dongxicheng.org/search-engine/thrift-guide/点击打开链接