利用apache Thrift 进行 node.js和 C++进程间通讯

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.cpp
server文件内容如下:

$ 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

里面的示例代码.这个网址比较有用 ^^




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值