Pure python approach of Apache Thrift(https://github.com/Thriftpy/thriftpy2.git

数据类型(IDL)

基本类型

  • bool: 布尔值 (true or false), one byte
  • byte: 有符号字节
  • i16: 16位有符号整型
  • i32: 32位有符号整型
  • i64: 64位有符号整型
  • double: 64位浮点型
  • string: 包括文本类型和二进制字符串
  • void: 方法无返回值,可以定义返回类型为 void


容器类型

  • list: 元素类型为t1的有序表,容许元素重复
  • set:元素类型为t1的无序表,不容许元素重复
  • map: 键类型为t1,值类型为t2的kv对,键不容许重复

枚举类型

枚举可以指定每个元素的值,也可以不指定,默认从 0 开始递增

  1. enum TweetType {
  2. TWEET,
  3. RETWEET = 2,
  4. DM = 0xa,
  5. REPLY
  6. }

结构体

thrift 要求每个域都必须有一个唯一的正整数标识符,结构体可以包含其它结构体,可以指定默认值

  1. struct Location {
  2. 1: required double latitude = 1.0;
  3. 2: required double longitude;
  4. }

常量

  1. const i32 INT_CONST = 1234;

其他

  • namespace – 用于指定不同语言生成的目录结构

    namespace cpp project namespace java com.example.project namespace php project

  • include – 用于引用其他 idl 文件

    include “tweet.thrift”

Thrift IDL

  1. const i16 DEFAULT_LIST_SIZE = 10
  2. typedef i32 timestamp
  3. enum PhoneType {
  4. MOBILE = 0,
  5. HOME,
  6. WORK,
  7. }
  8. struct PhoneNumber {
  9. 1: optional PhoneType type = PhoneType.MOBILE,
  10. 2: optional string number,
  11. }
  12. struct Person {
  13. 1: required string name,
  14. 2: optional list<PhoneNumber> phones,
  15. 3: optional timestamp created_at,
  16. }
  17. # 异常定义
  18. exception PersonNotExistsError {
  19. 1: optional string message = "Person Not Exists!",
  20. }
  21. service PersonService {
  22. bool add(1: required Person person);
  23. bool remove(1: string name) throws (1: PersonNotExistsError not_exists);
  24. Person get(1: string name) throws (1: PersonNotExistsError not_exists);
  25. }

服务端

  1. import asyncio
  2. import thriftpy2
  3. from thriftpy2.rpc import make_aio_server
  4. echo_thrift = thriftpy2.load("echo.thrift", module_name="echo_thrift")
  5. class Dispatcher(object):
  6. async def echo(self, param):
  7. print(param)
  8. await asyncio.sleep(0.1)
  9. return param
  10. def main():
  11. server = make_aio_server(
  12. echo_thrift.EchoService, Dispatcher(), '127.0.0.1', 6000)
  13. server.serve()
  14. if __name__ == '__main__':
  15. main()

客户端

同步

  1. import thriftpy2
  2. pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
  3. from thriftpy2.rpc import make_client
  4. client = make_client(pingpong_thrift.PingPong, '127.0.0.1', 6000)
  5. print(client.ping())

异步

仅支持Python3.5以上

  1. import thriftpy2
  2. import asyncio
  3. from thriftpy2.rpc import make_aio_client
  4. echo_thrift = thriftpy2.load("echo.thrift", module_name="echo_thrift")
  5. async def request():
  6. client = await make_aio_client(
  7. echo_thrift.EchoService, '127.0.0.1', 6000)
  8. print(await client.echo('hello, world'))
  9. client.close()

参考资源

分会场B-【5】从 Thriftpy 中学习 RPC 协议 - 张汝家.pdf

https://landybird.github.io/thrift/2019/01/26/thrift%E7%9A%84%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8(%E5%9B%9B)//)