Thrift协议分为数层。以下逐层分析其源代码。
一、传输层
传输层在其transport文件夹中。
TTransport.php中定义了TTransport类,这是是transport文件夹下所有具体类的基类。TTransport类定义了以下几个基本操作:
- 流是否打开
- 打开流
- 关闭流
- 读一定数量的字节
- 保证读一定数量字节(TTransport类中唯一的非抽象函数,利用上一个函数循环读取,一定保证读到指定数量的字节)
- 写出
- 刷新流
所有子类以不同方法定义了这些函数。子类中,有的定义完全,有的还有transport_字段(一个TTransport类对象),依靠transport_字段来实现操作。这说明所有的子类又可以分为两大类:底层的、定义完全的类,和上层的,依靠底层类才能工作的类。
定义完全的类有:
- TSocket。读写、刷新socket。
- THttpClient。通过HTTP资源读取,写入缓冲区,刷新时将缓冲区内的字节全部写出。
- TPhpStream。读写php://input和php://output。
- TMemoryBuffer。简单地读写一块内存。
- TNullTransport类。所有函数的定义都为空或者直接抛出异常,文件中写明“这个类只是用作测量结构体的size”。
- TBufferedTransport。其中有一块内存作为读缓冲区,一块内存作为写缓冲区。读写的时候实际只是在操作这两块缓冲区,知道读缓冲区中的字节不够本次读取,或者写缓冲区超过规定的大小,或者刷新流是,才利用其transport_字段进行实际的读写操作。
- TFramedTransport。其中也有一块读缓冲区,一块写缓冲区,一个读控制位,一个写控制位。开启读写控制时,每次读会读一整帧(先读帧头,解析出要读取多少字节,读取这些字节),写时先写到写缓冲区,刷新时先写帧头指明字节数量,再写数据。如果不开两个控制位,则使用期transport_字段直接进行读写操作。
二、协议层
协议层相关内容在protocol文件夹中。
TProtocol类是protocol文件夹下所有类的基类,其内部有一个TTransport对象的字段,用作通信动作。另外定义了较多的抽象函数:
- 消息相关:(read/write)Message(Begin/End) 用来开始/结束读写消息。看参数,要远程调用的函数名作为一个参数被传递过去;消息分为两种:调用和回复。
- 复杂的结构:读写Struct, Fields, Map, List, Set的Begin/End函数。消息和复杂结构可能需要标明开始与结束,因此需要Begin/End函数。
- 简单的结构:Bool, Byte, 数,字符串的读写函数。简单类型就不分Begin/End函数了。
- skip函数。接受一个类型作为参数,然后调用以上的函数得到该类型的一个值。
- skipBinary函数。接受一个TTransport对象和一个类型作为参数,从TTransport取出与类型长度一样的字节(不包括类型头部的知识信息)。