(1)thrift 简介
关于 thrift 详细介绍可以参考:https://www.cnblogs.com/cyfonly/p/6059374.html
1.1 thrift 支持的数据类型
1.1.1 基本类型
bool byte(有符号字节) i16(16位有符号整型) i32 i64 double(64位浮点型) string
1.1.2 结构体类型
类似 C 语言的结构体, struct UserDemo{1: i32 id; 2:string name; 3:i32 age =25; 4:string phone;}
1.1.3 容器类型
list<t> 元素类型为 t 的有序表
set<t> 元素类型为 t 的集合
map<t,t> 键类型为 t,值类型为 t 的 k-v 对
1.2 server 实现
TSimpleServer : 一次只服务一个连接
TNonblockingServer: 单线程处理多个连接
THshaServer: 用一个单独的线程处理网络 I/O,一个独立的 work 线程池来处理消息
TThreadedSelectorServer:维护 2 个线程池,一个用来处理网络 I/O,一个用来处理消息
TThreadPoolServer:一旦接受了一个连接,即开启一个线程,直到关闭。对系统资源消耗不太友好
(2)应用示例
2.1 首先定义一个 .thrift 格式的接口文件,比如 demo.thrift 定义简单的结构体 和 端口服务
struct DemoObject{
1:string x
2:i32 y
}
service DemoService{
string ping(1:string param)
DemoObject getObject(1:string x, 2:i32 y)
}
ping 函数输入一个字符串,返回一个字符串,getObject 函数输入一个字符串和整数,返回一个 DemoObject 对象。
2.2 然后通过以下命令生成接口代码
thrift --gen py demo.thrift
备注:如果是生成 java 或 c++ 接口则如下
thrift --gen java demo.thrift
thrift --gen cpp demo.thrift
2.3 以上会生成一个 gen-py 文件夹。里面会有一个 demo 文件夹,demo文件夹里面会包含两个文件
1.DemoSerivce.py python 的服务端 & 客户端所依赖的类定义
2.ttypes.py 接口所涉及的数据类型定义
gen-py/demo 中的文件如下:
2.4 编写 server 服务代码 demo_server.py,依赖于上面生成的文件,内容如下:
import sys
sys.path.append("./gen-py/")
# 加载 demo 中定义的依赖类
from demo import DemoSerivce
from demo.ttypes import DemoObject
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class DemoServer:
def __init__(self):
self.log = {}
# 定义 ping 函数
def ping(self, param):
return "Got ping request: " + param
# 定义 getObject 函数
def getObject(self, x, y):
return DemoObject(x, y)
if __name__ == '__main__':
# 创建服务端
handler = DemoServer()
processor = DemoSerivce.Processor(handler)
# 监听端口
transport = TSocket.TServerSocket(host = "0.0.0.0" ,port=10000)
# 选择传输层
tfactory = TTransport.TBufferedTransportFactory()
# 选择传输协议
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
# 创建服务端
server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
# 设置连接线程池数量
server.setNumThreads(10)
# 启动服务
server.serve()
2.5 运行 demo_server.py 启动接口服务
python demo_server.py
2.6 编写客户端代码,也可以用到 gen-py/demo Demoservice.py 中定义好的 Client 类
2.6.1 python 客户端示例 demo_client.py
import sys
sys.path.append("./gen-py/")
from demo import DemoSerivce
from demo.ttypes import DemoObject
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
if __name__ == '__main__':
transport = TSocket.TSocket('127.0.0.1', 10000)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = DemoSerivce.Client(protocol)
# connect
transport.open()
ping = client.ping("test") # 调用 ping 函数
print ping
demo_obj = client.getObject("xxx", 2) # 调用 getObject 函数
print '%s\t%d' % (demo_obj.x, demo_obj.y)
# close
transport.close()
运行结果如下:
2.6.2 java 客户端代码示例 demo_client.java
package com.miaolegemitong.demo.thrift.client;
import com.miaolegemitong.demo.thrift.client.autogenerated.DemoObject;
import com.miaolegemitong.demo.thrift.client.autogenerated.DemoSerivce;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
public class JavaClientNative {
public static void main(String[] args) {
TTransport transport;
try {
//修改服务器和端口
transport = new TSocket("127.0.0.1", 10000);
TProtocol protocol = new TBinaryProtocol(transport);
DemoSerivce.Client client = new DemoSerivce.Client(protocol);
transport.open();
System.out.println(client.ping("test"));
DemoObject object = client.getObject("xxx", 2);
System.out.println(object.getX() + "\t" + object.getY());
transport.close();
} catch (TException e) {
e.printStackTrace();
}
}
}