最近在使用thrift框架准备干些事情,在学习thrift的过程中发现大家都是在使用同一种语言在进行Server和Client,因为我这个是使用多种语言的,刚开始,对这个过程不熟悉,而且好多示例都是使用同一种语言,有些迷糊。中间查看了好些资料,走过一些弯路,现在在此用一个小示例说明,不同语言通过thrift如何进行工作。而且我工程这个有点怪异,一般使用是Server端使用C++,Client端使用Python,而我正好相反:Server端使用Python,Client端使用C++。
thrift的知识在此不做叙述,这个直接去官网比较靠谱。
下面举一个小的例子,在linux下实施C++ Client端发送一个加法请求,Python Server端进行加法运算,最后把结果从Server返回给Client端。是的就是这个加法小例子,举着个例子还有一个原因就是thrift安装程序中自带的那个计算器C++例子不能跑起来,太坑了。
1、定义一个thrift文件
在此定义Calculator.thrift,其内容如下:
service AddOpt {i32 Add(1:i32 Num1,2:i32 Num2)}
2、生成Python和C++接口文件
在终端执行下面语句:
thrift --gen py Calculator.thrift
thrift --gen cpp Calculator.thrift
执行上述两条语句后会在当前目录下生成gen-py和gen-cpp文件夹
下面看看在文件夹下都产生了啥东西。
2.1 gen-py文件夹
下面这张图是gen-py文件夹下的文件
下面这张图是Calculator文件夹下的文件
其中AddOpt是刚才在thrift文件内容:
service AddOpt {i32 Add(1:i32 Num1,2:i32 Num2)}中的AddOpt,其他几个文件为这个文件服务用。
现在只需稍微注意一下AddOpt.py文件,后面会用到一下其中的方法。
2.2 gen-cpp文件夹
相对于python,c++就直接一些,直接呈现文件。
这些文件和python的类似,其中AddOpt_server.skeleton.cpp用于搭建写Server端程序挺方便的。但我把C++作为Client端,因此这个永不上。
3 搭建Server端Python程序
Server端Python程序为Server.py,其代码如下:
import sys
sys.path.append('gen-py') #加入接口文件
from Calculator import AddOpt
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class AddOptHandler(object):
def Add(self,Num1,Num2):#接口加法函数的最终实现
print 'Server receive Add request from Python'
Msg='Server Adding {}+{}\n'.format(Num1,Num2)
print (Msg)
return int(Num1+Num2)
if __name__ == '__main__':
handler = AddOptHandler()#服务端最终处理类
processor = AddOpt.Processor(handler)
transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)#本地地址
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
# You could do one of these for a multithreaded server
# server = TServer.TThreadedServer(
# processor, transport, tfactory, pfactory)
# server = TServer.TThreadPoolServer(
# processor, transport, tfactory, pfactory)
print('Starting the server...')
server.serve()
print('done.')
4、搭建Client 端C++程序
Client 端C++程序Client.cpp.其代码如下:
#include <iostream>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include "./gen-cpp/AddOpt.h" #包含接口文件
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace std;
int main(int argc, char **argv)
{
stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));
stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
AddOptClient client(protocol);//申明一个AddOptClient(AddOpt为thrift定义中的AddOpt,这个结构是固定:xxClient,其中xx为thrift文件中的申明 的名)请求对象client
transport->open();
cout << "Client sent Add request from C++"<<endl;
int sum_ = client.Add(10, 1);//发送请求并等待接受结果
cout << "10+1= " << sum_<< endl;
transport->close();
return 0;
}
因为C++文件是需要预先编译的,所以我们在此使用g++先把它编译成可执行文件才能进行demo通信。
编译这个含有thrift相关库的cpp文件会遇到一些坑,在此我们才靠wiki上的thrift官网给的一个例子来进行吧
编译C++示例:https://wiki.apache.org/thrift/ThriftUsageC++
4.1 编译Client.cpp
编译过程为在当前目录依次执行:
cd ..
g++ -Wall -I/usr/local/include/thrift -c Client.cpp -o Client.o
g++ -L/usr/local/lib Client.o ./gen-cpp/AddOpt.o ./gen-cpp/constants.o ./gen-cpp/types.o -o Client -lthrift
g++ Client.cpp -o Client -lthrift
g++ -Wall -I/usr/local/include/thrift -c Client.cpp -o Client.o
g++ -L/usr/local/lib Client.o ./gen-cpp/AddOpt.o ./gen-cpp/constants.o ./gen-cpp/types.o -o Client -lthrift
5、Server和Client端进行通信
首先启动Server端,执行:python Server.py
然后启动Client端,执行:./Client
好了至此这个两种语言通信的过程大致就是如此了,其他后面再说把。
最后关于thrift的一些好的文章放置在此吧
1、thrift官网
2、C++示例,过程很详细也给出了一些错误处理方法
https://www.cnblogs.com/zhaoxd07/p/5387215.html
3、关于编译C++文件报错未定义引用的一些处理方法
https://stackoverflow.com/questions/9956861/thrift-cpp-sample-code-compile-error
4、试验thrift做后端rpc,nginx做web服务器, python后端php前端
https://www.cnblogs.com/LarryGates/p/6596232.html