疯狂Get新技能ing
安装Thrift
- 一般情况下,需要用apt来安装
- Conda安装的话只有Python相关的模块,C++用不了
写一个thrift文件
比如,叫做 hello.thrift
service DemoService{
i32 add(1: i32 a, 2: i32 b),
string say(1: string data),
string ping()
}
这个例子只有服务。除此之外,还可以有数据结构定义。
生成对应的接口
Python
thrift --gen py hello.thrift
会生成 gen-py
文件夹,将里面的东西作为一个包拿出来用,或者是在代码里面将这个路径加入path
import path
sys.path.append('gen-py')
C++(CMakefiles文件要自己写啊~我不会)
thrift --gen cpp hello.thrift
如果有其他什么免写CMakefiles文件的方法……请告诉我!
使用
Python
客户端
import sys
import glob
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift_py.hello import DemoService
def main():
# Make socket
transport = TSocket.TSocket('localhost', 4134)
# 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 = DemoService.Client(protocol)
transport.open()
print(client.ping())
print('1+100=%d' % client.add(1, 100))
transport.close()
if __name__ == '__main__':
try:
main()
except Thrift.TException as tx:
print('%s' % tx.message)
服务端有自动生成的代码,可以直接改改用,将里面几个业务函数(add/ping/say)补完整即可
C++
服务端,自动生成的代码没什么坑,只是不知道该怎么把声明和实现分开。
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TServerSocket.h>
#include <iostream>
#include "thrift/DemoService.h"
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
class DemoServiceHandler : virtual public DemoServiceIf {
public:
DemoServiceHandler() = default;
int32_t add(const int32_t a, const int32_t b) {
// Your implementation goes here
std::cout << "Add: " << a << "+" << b << std::endl;
return a + b;
}
void say(std::string &_return, const std::string &data) {
// Your implementation goes here
std::cout << "Say: " << data << std::endl;
_return = "You said:" + data;
}
void ping(std::string &_return) {
// Your implementation goes here
std::cout << "Ping" << std::endl;
_return = "Pong";
}
};
int main(int argc, char **argv) {
int port = 4134;
shared_ptr<DemoServiceHandler> handler(new DemoServiceHandler());
shared_ptr<TProcessor> processor(new DemoServiceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(
new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory,
protocolFactory);
std::cout << "Start server at port " << port << std::endl;
server.serve();
std::cout << "Done." << std::endl;
return 0;
}
客户端,也直接用官方Demo吧:
#include <iostream>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include "thrift/DemoService.h"
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
int main() {
std::cout << "I'm Client" << std::endl;
std::shared_ptr<TTransport> socket(new TSocket("localhost", 4134));
std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
DemoServiceClient client(protocol);
try {
transport->open();
std::string send = "Lalala";
std::string received = "";
std::cout << "ping()" << std::endl;
client.ping(received);
std::cout << received << std::endl;
std::cout << "1 + 1 = " << client.add(1, 1) << std::endl;
client.say(received, send);
std::cout << received << std::endl;
transport->close();
} catch (TException& tx) {
std::cout << "ERROR: " << tx.what() << std::endl;
}
return 0;
}
另外就是要注意一下参数的顺序和要求……比如,thrift里返回为string
的,在客户端这里都是string&
,需要先定义一个string
再传进去,并且好像一般返回值是第一个参数。这一点比较不适应。
使用建议
用C++写服务端(运行速度比较快) 用Python写客户端(开发速度比较快)
为啥这样说呢?——gen之后,默认生成的代码里面,cpp给的是服务端代码,python给的是客户端代码。——人家都替你想好啦~
使用建议2
Python的话,有个东西叫 ThriftPy2,可以直接加载thrift idl文件,而不用首先生成Python代码,而且可以一键生成Client,甚是方便。
发表回复