Apache thift 是 facebook开发的一个支持跨语言进程通讯的软件框架.
下面说明node.js 和 C++如何借助于 它进行通讯.
1. 首先, 创建一个 thrift IDL 文件 my.thrift, 如下:
#!/usr/local/bin/thrift --gen cpp namespace cpp Test service Something { i32 ping() }ping 是一个 node.js 和 C++ IPC的 接口.
2. 运行命令,创建出 C++文件:
thrift --gen cpp my.thrift这时,会在当前目录下,生成一个 gen-cpp 目录和一些文件:
$ tree . . ├── gen-cpp │ ├── my_constants.cpp │ ├── my_constants.h │ ├── my_types.cpp │ ├── my_types.h │ ├── Something.cpp │ ├── Something.h │ └── Something_server.skeleton.cpp └── my.thrift 1 directory, 8 files自动生成了一个 server 文件 Something_server.skeleton.cpp.
运行下面的命令:
cp Something_server.skeleton.cpp Something_server.cppserver文件内容如下:
$ cat Something_server.cpp // This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "Something.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 ::Test; class SomethingHandler : virtual public SomethingIf { public: SomethingHandler() { // Your initialization goes here } int32_t ping() { // Your implementation goes here printf("ping, server-side api is called\n"); } }; int main(int argc, char **argv) { int port = 9090; shared_ptr<SomethingHandler> handler(new SomethingHandler()); shared_ptr<TProcessor> processor(new SomethingProcessor(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. client 文件没有自动生成,需要手动写一个:
$ cat Something_client.cpp #include "Something.h" // As an example #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<TSocket> socket(new TSocket("localhost", 9090)); boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); SomethingClient client(protocol); transport->open(); printf("call ping ........\n"); client.ping(); transport->close(); return 0; }
5.写一个makefile文件, 如下:
$ cat Makefile GEN_SRC := Something.cpp my_constants.cpp my_types.cpp GEN_OBJ := $(patsubst %.cpp,%.o, $(GEN_SRC)) THRIFT_DIR := /usr/local/include/thrift BOOST_DIR := /usr/local/include INC := -I$(THRIFT_DIR) -I$(BOOST_DIR) .PHONY: all clean all: something_server something_client %.o: %.cpp $(CXX) -Wall -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H $(INC) -c $< -o $@ something_server: Something_server.o $(GEN_OBJ) $(CXX) $^ -o $@ -L/usr/local/lib -lthrift something_client: Something_client.o $(GEN_OBJ) $(CXX) $^ -o $@ -L/usr/local/lib -lthrift clean: $(RM) *.o something_server something_client
运行 make,会生成两个可执行文件: something_client 和 something_server
6.测试 C++之间 的 IPC:
$ ./something_server & [1] 18211 $ ./something_client call ping ........ ping, server-side api is called
7. 现在配置 node.js:
$ thrift --gen js:node my.thrift
同样,生成一个 gen-nodejs的目录和一些文件:
$ tree gen-nodejs/ gen-nodejs/ ├── my_types.js └── Something.js 0 directories, 2 files
创建一个 client 文件如下:
$ cat client.js var thrift = require('thrift'); var service = require('./Something.js') ttypes = require('./my_types'); var connection = thrift.createConnection('localhost', 9090); connection.on("error", function(err) { console.error(err); }); var client = thrift.createClient(service, connection); client.ping(); connection.end();
执行npm命令,安装 thrift 库:
$ npm install thrift npm http GET https://registry.npmjs.org/thrift npm http 304 https://registry.npmjs.org/thrift thrift@0.7.0 node_modules/thrift
因为, 目前,对于 node.js, TBufferedTransport的模式还不支持,所以要改一下 C++文件,把 TBufferedTransport改成 TframedTransport
改动后的文件如下:
$ cat Something_server.cpp // This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "Something.h" #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h> #include <thrift/transport/TServerSocket.h> #include <thrift/transport/TTransportUtils.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 SomethingHandler : virtual public SomethingIf { public: SomethingHandler() { // Your initialization goes here } int32_t ping() { // Your implementation goes here printf("ping, Ha ha, you got it\n"); } }; int main(int argc, char **argv) { int port = 9090; shared_ptr<SomethingHandler> handler(new SomethingHandler()); shared_ptr<TProcessor> processor(new SomethingProcessor(handler)); shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); shared_ptr<TTransportFactory> transportFactory(new TFramedTransportFactory()); shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); printf("starting a server ..........\n"); server.serve(); return 0; }
8.重新运行 make, 生成新的 server程序.
然后测试
$ ./something_server & [1] 19532 $ node ./client.js ping, Ha ha, you got it
P.S.
C++代码部分,参考了
http://wiki.apache.org/thrift
里面的示例代码.这个网址比较有用 ^^
作者:CaspianSea 发表于2013-3-16 23:12:08 原文链接
阅读:64 评论:0 查看评论