Thrift 传输层简单介绍。


传输层类关系图

传输层类关系图主要分为三部分来看:

  • 抽象基类 TTransport,它是所有传输类的基类,有很大一部分类直接从它继承实现它定义的接口函数(纯虚函数)
  • TTransport 的默认实现 TTransportDefaults 类和虚拟传输类 TvirtualTransport 及其子类
  • 各种传输类的对象生成工厂类,负责某一种具体传输类对象的生产

TTransport

源码路径:thrift/lib/cpp/src/thrift/transport/TTransport.h

模板函数 readAll

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
template <class Transport_>
uint32_t readAll(Transport_& trans, uint8_t* buf, uint32_t len) {
  uint32_t have = 0;
  uint32_t get = 0;

  while (have < len) {
    get = trans.read(buf + have, len - have);   // 通过具体的传输类对象读取剩余的需要读取的数据
    if (get <= 0) {
      throw TTransportException(TTransportException::END_OF_FILE, "No more data to read.");
    }
    have += get;    // 已读取的字节数
  }

  return have;  // 返回读取得字节数
}

TTransport 的接口定义

  1. isOpen():transport 是否 open

  2. peek():测试是否仍然有数据可读或远程 transport 是否 open

  3. open():打开 transport

  4. close():关闭 transport

  5. read() & read_virt():尝试读取指定的字节数到字符串

    • uint8_t* buf:Reference to the location to write the data
    • uint32_t len: How many bytes to read
  6. readAll() & readAll_virt():必须读取指定长度的数据

    • uint8_t* buf:Reference to location for read data
    • uint32_t len: How many bytes to read
  7. readEnd():读取完成时调用

  8. write() & write_virt():将字符串写入缓存

    • uint8_t* buf:The data to write out
    • uint32_t len: How many bytes to write
    • 必须调用 flush() 才能确保成功写入,析构一个 TTransport 对象并不会自动 flush pendng data.
  9. writeEnd():写入完成时调用

  10. flush():Flushes any pending data to be written.

  11. borrow() & borrow_virt():尝试返回一个指向长为 len 的字符串缓存而不真正地读取消耗它

    • uint8_t* buf:A buffer where the data can be stored if needed.
    • uint32_t* len: len should initially contain the number of bytes to borrow.
  12. consume() & consume_virt():从传输层消耗 len 字节的数据

    • uint32_t len: How many bytes to consume

通常一个传输层的对象要么作为输出要么作为输入,但是通常不能同时作为输入和输出。上述已把所有支持的接口操作都简单的介绍了,后面介绍的具体某一个传输层类的实现都会实现这些接口,只是根据各个子类不同的作用和实现方式有不同而已。特别需要注意的是最后两组函数,这两组函数主要是用于支持可变长度编码的,所以如果传输层对象需要支持可变长度编码必须实现这两组函数。

TTransportDefaults

源码路径:thrift/lib/cpp/src/thrift/transport/TTransport.h/TVirtualTransport.h

默认传输类 TTransportDefaults 是 TTransport 的子类,提供了抽象类 TTransport 的默认实现,实现了非虚拟的方法 *_virt() 方法。

TVirtualTransport

源码路径:thrift/lib/cpp/src/thrift/transport/TTransport.h/TVirtualTransport.h

虚拟传输类 TVirtualTransport 采用了模板的方式来实现多继承(同时从两个类继承),也就是说可以从一个默认的类继承,而另一个类采用模板参数传递。而默认传输类的作用就是防止那些没有实现默认传输类实现的方法的子类造成递归调用(死循环了)。