Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

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

$
0
0

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

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




作者:CaspianSea 发表于2013-3-16 23:12:08 原文链接
阅读:64 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>