Thrift的文档真是不是一般的incomplete 基本上可以说是空白. Facebook不知道干什么去了. 这是我找到的有点帮助的文档:
官方的文档: Using Thrift with C++,
网上其他的: A Intro to Thrift
安装
Thrift 的C++编译器使用了boost,所以你如果要用Thrift配合C++使用的话, 需要先安装boost.
然后下载thrift源代码,编译安装(configure, make, make install),按下不表.
HelloWorld (C++版)
第一步:用thrift描述一个service的接口,比如在Server端提供这样一个函数叫ping, Client端可以通过rpc调用ping这个函数(在thrift帮你marshall这些rpc call),ping会在Server端执行.
namespace cpp Test service HelloWorld { oneway void ping() }将这个文件存为比如apc999.thrift. 现在把编译apc999.thrift成C++代码
$thrift --gen cpp apc999.thrift $ls gen-cpp/ HelloWorld.thrift/ $ls gen-cpp apc999_constants.cpp apc999_types.cpp HelloWorld.cpp HelloWorld_server.skeleton.cpp apc999_constants.h apc999_types.h HelloWorld.h在gen-cpp这个目录中, 我们会发现一堆thrift生成的文件. 其中HelloWorld开头的都是和HelloWorld这个service有关, 你可以在apc999.thrift中定义多个service.他们会生成不同的文件. 而apc999开头的是一些常量和类型的定义.
我们需要记住的是: Thrift帮你生成了给定Service的服务器端和客户端代码.Thrift这里的命名规则是对于Service XYZ, 它对应的服务器端代码(具体这个Service的执行)在类XYZHandler中,客户端代码(负责marshall, execute RPC)在类XYZClient中. 所以你需要用这个服务, 你只需要直接修改或者继承这些类.
第二步:编写Server端代码. thrift帮我们生成的HelloWorld_server.skeleton.cpp就是Server端代码的模板. 我们只需要往里面添加我们需要的功能实现. 比如我们添加了一行
// This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "HelloWorld.h" #include <protocol/TBinaryProtocol.h> #include <server/TSimpleServer.h> #include <transport/TServerSocket.h> #include <transport/TBufferTransports.h> using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; using boost::shared_ptr; using namespace Test; class HelloWorldHandler : virtual public HelloWorldIf { public: HelloWorldHandler() { // Your initialization goes here } void ping() { // Your implementation goes here printf("Hello World!\n"); //目前为止我修改的唯一一行 } }; int main(int argc, char **argv) { int port = 9090; shared_ptr<HelloworldHandler> handler(new HelloWorldHandler()); shared_ptr<TProcessor> processor(new HelloWorldProcessor(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); server.serve(); return 0; }这个Server端代码有main函数, 所以你完全可以编译这个程序并运行.它会在9090端口监听. 如果有rpc调用ping这个函数, 它会打印出"Hello World!".
第三步:编写客户端代码.
#include "HelloWorld.h" // HelloWorldClient这个类在helloWorld.h中被申明 #include <transport/TSocket.h> #include <transport/TBufferTransports.h> #include <protocol/TBinaryProtocol.h> using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace Test; int main(int argc, char **argv) { boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); HelloWorldClient client(protocol); transport->open(); client.ping(); transport->close(); return 0; }
Tips
Thrift生成的server端是thread safe的. 但是client端不是thread safe. 所以需要多个thread和server端通信,则每个thread需要initiate一个自己的client实例.
使用Thrift的C++库有,server端有4种不同的选择: TSimpleServer,TThreadedServer, TThreadPoolServer,以及TNonblockingServer.
当有server和client间有大量的network traffic的时候,可以使用Nagles算法来优化网络性能. Nagles算法通过缓冲来减少收发的packet数目.在Thrift中使用Nagles算法,我们只需要将上面例子中的客户端代码中下面的语句
boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));改为
TSocket* sock = new TSocket("localhost", 9090); boost::shared_ptr<TTransport> socket(sock);然后在调用transport->open();之前 先调用sock->setNoDelay(false);就可以了
No comments:
Post a Comment