本文主要简单记录rpc框架thrift的使用,详细可查thrift官网
第一步:安装thrift
命令行输入 brew install thrift (此方法仅适用于mac,其他安装方法查看教程)
第二步:编写一个.thrift文件
首先这个.thrift文件是什么作用呢?其实这个文件主要用类c语言的写法定义一些常量、结构、类和方法。
然后为什么要定义这个.thrift文件呢? 我们知道thrift RPC框架是可以支持20多中语言的如python、java、go、php、C++等,我们需要定义这个.thrift文件,然后通过thrift程序把它转换成你需要语言的格式,也就是我们第三步要做的。
这里我们写个rpc.thirft文件示例:
namespace py rpc
namespace java rpc
namespace go rpc
//上面内容可以省略
//定义常量示例
const string HELLO_WORLD= "world"//定义结构体示例
struct Resp{1: i32 Code=0,2: string Msg="",
}
//定义接口示例
service HelloWorld {
void ping(), //接口方法
Resp sayHello(), /接口的返回值为Resp结构体形式
string sayMsg(1:string msg)
}
第三步:把根据我们定义的.thrift文件,thrift自动生成代码
命令行输入 thrift --gen
例如我们是python语言,然后文件名为rpc.thrift所以我们输入命令
thrift --gen py pc.thrift
在你输入完命令刷新后,会自动出现gen-py目录,我们可以将它理解为我们RPC程序的脚手架
第四步:有了脚手架后,我们就可以编写客户端和服务端了
客户端文件示例 client.py:
importsys
sys.path.append('./gen-py')from rpc importHelloWorldfrom rpc.ttypes import *
from rpc.constants import *
from thrift importThriftfrom thrift.transport importTSocketfrom thrift.transport importTTransportfrom thrift.protocol importTBinaryProtocoltry:#Make socket
transport = TSocket.TSocket('127.0.0.1', 30303)#Buffering is critical. Raw sockets are very slow
transport =TTransport.TBufferedTransport(transport)#Wrap in a protocol
protocol =TBinaryProtocol.TBinaryProtocol(transport)#Create a client to use the protocol encoder
client =HelloWorld.Client(protocol)#Connect!
transport.open()
client.ping()print("ping()")
msg=client.sayHello()print(msg, type(msg))
# 这里发送的是之前文件中定义的常量HELLO_WORD
msg=client.sayMsg(HELLO_WORLD)print(msg)
transport.close()exceptThrift.TException as tx:print("%s" % (tx.message))
然后编写服务端程序service.py:
importsys
sys.path.append('./gen-py')from rpc importHelloWorldfrom rpc.ttypes import *
from thrift.transport importTSocketfrom thrift.transport importTTransportfrom thrift.protocol importTBinaryProtocolfrom thrift.server importTServerimportsocketclassHelloWorldHandler:def __init__(self):
self.log={}defping(self):print("ping()")defsayHello(self):print("sayHello()")
# 这里我返回的是之前定义的Resp结构体return Resp(1, "hahah")defsayMsg(self, msg):print(1212)returnmsg
handler=HelloWorldHandler()
processor=HelloWorld.Processor(handler)
transport= TSocket.TServerSocket('127.0.0.1', 30303)
tfactory=TTransport.TBufferedTransportFactory()
pfactory=TBinaryProtocol.TBinaryProtocolFactory()
server=TServer.TSimpleServer(processor, transport, tfactory, pfactory)print("Starting python server...")
server.serve()print("done!")
这两个文件放在gen-py目录下
第五步:先启动service端,然后再启动client端
然后你查看控制台就可以看到,客户端与服务端之间的通信输出了如:
service端:
/usr/local/bin/python3.7 /Users/bytedance/PycharmProjects/untitled5_django/rpc/service.py
Starting python server...
ping()
sayHello()1212
client端输出:
/usr/local/bin/python3.7 /Users/bytedance/PycharmProjects/untitled5_django/rpc/client.py
ping()
Resp(Code=1, Msg='hahah') world
Process finished with exit code 0