1 创建thrift文件
thrift文件非常简单,一个WorkerManager提供了一个ping方法,让客户端通过RPC方式远程调用,模拟icmp协议的ping,看看服务端是否正常.
# worker.thrift # Dean Chen (csfreebird@gmail.com) # /** * Thrift files can namespace, package, or prefix their output in various * target languages. */ namespace cpp freebird /** * Defining a removed class named WorkerManager */ service WorkerManager { /** * client calls ping method to make sure service process is active or dead */ void ping() }
2 生成C++代码
用thrift命令行就可以生成C++代码,包括服务器端代码:
thrift -r --gen cpp -o ../ worker.thrift
上面的命令会在../目录创建gen-cpp目录,里面包含了所有生成的C++代码.
worker_constants.cpp worker_constants.h WorkerManager.cpp WorkerManager.h WorkerManager_server.skeleton.cpp worker_types.cpp worker_types.h
WorkerManager_server.skeleton.cpp就是C++服务端的main函数入口文件,里面使用了TSimpleServer作为TCP服务,性能较低,但是实现简单,比较合适做进程管理类的接口. 这目前就是我需要的.因为我的一个程序中就是需要能够远程对worker进程进行状态查询和任务控制,而不是传递大量的数据. 下面是自动产生的代码:
// This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "WorkerManager.h" #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h> #include <thrift/transport/TServerSocket.h> #include <thrift/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 ::freebird; class WorkerManagerHandler : virtual public WorkerManagerIf { public: WorkerManagerHandler() { // Your initialization goes here } /** * client calls ping method to make sure service process is active or dead */ void ping() { // Your implementation goes here printf("ping\n"); } }; int main(int argc, char **argv) { int port = 9090; shared_ptr<WorkerManagerHandler> handler(new WorkerManagerHandler()); shared_ptr<TProcessor> processor(new WorkerManagerProcessor(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; }
3 编写C++客户端代码
客户端程序需要自己编写:
#include <iostream> #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/transport/TSocket.h> #include <thrift/transport/TTransportUtils.h> #include "../../server/gen-cpp/WorkerManager.h" using namespace std; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace freebird; int main() { 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)); WorkerManagerClient client(protocol); try { transport->open(); client.ping(); cout << "ping()" << endl; transport->close(); } catch (TException& tx) { cout << "ERROR: " << tx.what() << endl; } }
4 例子项目
4.1 项目目录
thrift_base$ tree -L 2 . ├── client │ ├── builder │ ├── include │ └── src └── server ├── builder ├── gen-cpp └── thrift
4.2 编译服务端
sever目录下除了thrift目录里的thrift文件外,没有任何额外的C++代码gen-cpp是命令行产生的. 用下面的命令进行编译
cd builder ./rebuild.lsp debug_config.lsp
builder/bin目录下的thrift_server是可执行程序
4.3 编译客户端
client目录下src目录里的main.cc文件是唯一手写的代码,编译后在builder/bin目录下出现thrift_client可执行程序. 用下面的命令进行编译
cd builder ./rebuild.lsp debug_config.lsp
4.4 运行
先启动服务端程序,监听9099端口,然后启动客户端程序,调用服务端的ping方法,服务端控制台打印出文字. 一切工作正常.