在之前的文章中,我们简单的介绍了什么是Thrift以及Thrift的基本功能。
在本文中,我们将会以一个Python示例来讲解如何利用Thrift构建一个Server并使用Client对其进行调用。
环境准备
为了简便,本文中我们将以Docker镜像的方式使用Thrift。
使用Docker的优势是可以忽略整体依赖环境的搭建,只需要本机安装有Docker即可。
Docker的安装可以参考如下文章:
https://www.missshi.cn/api/view/blog/5a6327650a745f6335000002
安装完成Docker后,我们直接执行如下命令即可从Dockerhub中获取到我们所需要的镜像:
docker pull thrift
创建Thrift文件
如下为一个简单的Thrift文件HelloService.thrift
。
service HelloService {
void sayHello()
string getData(1:string input)
}
在该文件中,我们定义了一个HelloService
的服务,这个服务中包含了两个接口:
- sayHello:该函数不需要输入值,也没有返回值
- getData:该函数有一个字符串作为输入值,同时有一个字符串作为返回值。
编译Thrift文件
当我们编写完成Thrift文件后,可以执行如下代码来编译Thrift文件,从而生成一个Python的项目文件夹。
docker run -v "$PWD:/data" thrift thrift -o /data --gen py /data/HelloService.thrift
其中:
-v "$PWD:/data"
表示将当前目录映射到容器的/data
文件夹。-o
表示输出文件夹的位置在/data
目录下。--gen py
表示生成Server端的代码是Python项目。/data/HelloService.thrift
指定了要编译的Thrift文件。
执行完成后,我们查看当前文件夹可以发现目前在文件夹下已经有了一个新的文件夹,名为gen-py
。
上图为当前文件夹的目录树结构。
编写Server文件
下面,我们可以在gen-py
文件夹下创建一个Server端的server.py
文件,用于实现在thrift文件中定义的接口的功能:
from HelloService import HelloService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class HelloServiceHandler:
"""
# HelloServiceHandler是中定义的方法用于实现在thrift文件中定义的接口
"""
def __init__(self):
self.log = {}
def sayHello(self):
# sayHello接口的实现
print ('sayHello')
def getData(self, input):
# getData接口的实现
return input+' from server 1024'
# 实例化Handler
handler = HelloServiceHandler()
# 根据handler创建一个processor
processor = HelloService.Processor(handler)
# 指定端口启动transport
transport = TSocket.TServerSocket(port=9090)
# 创建tfactory, pfactory
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
# 创建Server
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print ('Starting the server...')
# 启动server
server.serve()
print ('done.')
启动Server
server.py
文件编写完成后,我们可以在gen-py
文件夹下启动Server服务:
python server.py
创建Client文件
Server端服务启动后,为了测试Server端的服务是否能够正常启动,我们需要创建一个Client调用文件client.py
。
from HelloService import HelloService
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
# 连接Socket
transport = TSocket.TSocket('localhost', 9090)
# 获取Transport
transport = TTransport.TBufferedTransport(transport)
# 获取TBinaryProtocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# 创建一个Client
client = HelloService.Client(protocol)
# 连接通道transport
transport.open()
# 调用某个没有返回值的函数
client.sayHello()
# 调用某个有返回值的函数
print(client.getData("client access"))
# 关闭通道transport
transport.close()
except Thrift.TException as tx:
print ('%s' % (tx.message))
实验一下吧:
Server端服务已经正常启动了,同时我们也已经编写好了Client端的测试文件,下面,我们来运行一下client.py
文件测试一下吧:
python client.py
此时,如果一切服务正常的话,在client端的输出中,我们可以看到打印如下内容:
client access from server 1024
而在Server端可以看到打印了如下内容:
sayHello