一直在用thrift,服务器用C++开发,想学习用node.js做客户端连接C++服务器,就安装了node.js thrift,tutorial中的例子有NodeClient.js 和NodeServer.js 其中NodeClient.js的代码 var thrift = require(‘thrift’); var ThriftTransports = require(‘thrift/transport’); var ThriftProtocols = require(‘thrift/protocol’); var Calculator = require(’./gen-nodejs/Calculator’); var ttypes = require(’./gen-nodejs/tutorial_types’);
transport = ThriftTransports.TBufferedTransport() protocol = ThriftProtocols.TBinaryProtocol()
var connection = thrift.createConnection(“localhost”, 9090, { transport : transport, protocol : protocol });
connection.on(‘error’, function(err) { assert(false, err); });
// Create a Calculator client with the connection var client = thrift.createClient(Calculator, connection);
client.ping(function(err, response) { console.log(‘ping()’); });
client.add(1,1, function(err, response) { console.log(“1+1=” + response); });
work = new ttypes.Work(); work.op = ttypes.Operation.DIVIDE; work.num1 = 1; work.num2 = 0;
client.calculate(1, work, function(err, message) { if (err) { console.log("InvalidOperation " + err); } else { console.log(‘Whoa? You know how to divide by zero?’); } });
work.op = ttypes.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10;
client.calculate(1, work, function(err, message) { console.log(‘15-10=’ + message);
client.getStruct(1, function(err, message){ console.log('Check log: ’ + message.value);
//close the connection once we're done
connection.end();
}); }); NodeServer.js可以正常运行,但是NodeClient.js运行出错,提示 找不到thrift/transport
其实查看thrift目录下的源码,可以看到index.js里面已经导出了transport,所以可以直接使用导出的thrift, 修改代码为 var thrift = require(‘thrift’); var Calculator = require(’./gen-nodejs/Calculator’); var ttypes = require(’./gen-nodejs/tutorial_types’);
transport = thrift.TBufferedTransport protocol = thrift.TBinaryProtocol
var connection = thrift.createConnection(“localhost”, 9090, { transport : transport, protocol : protocol });
connection.on(‘error’, function(err) { assert(false, err); });
// Create a Calculator client with the connection var client = thrift.createClient(Calculator, connection);
client.ping(function(err, response) { console.log(‘ping()’); });
client.add(1,1, function(err, response) { console.log(“1+1=” + response); });
work = new ttypes.Work(); work.op = ttypes.Operation.DIVIDE; work.num1 = 1; work.num2 = 0;
client.calculate(1, work, function(err, message) { if (err) { console.log("InvalidOperation " + err); } else { console.log(‘Whoa? You know how to divide by zero?’); } });
work.op = ttypes.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10;
client.calculate(1, work, function(err, message) { console.log(‘15-10=’ + message);
client.getStruct(1, function(err, message){ console.log('Check log: ’ + message.key + message.value);
//close the connection once we're done
connection.end();
}); }); 此时可以正常运行,
示例代码中的一些问题 var thrift = require(‘thrift’); var ThriftTransports = require(‘thrift/transport’); var ThriftProtocols = require(‘thrift/protocol’); var Calculator = require(’./gen-nodejs/Calculator’); var ttypes = require(’./gen-nodejs/tutorial_types’);
transport = ThriftTransports.TBufferedTransport() protocol = ThriftProtocols.TBinaryProtocol()
transport 应为Thriftransports.TBufferedTransport和thrift.TBufferedTransport等效 protocol 应为ThriftProtocols.TBinaryProtocol和thrift.TBinaryProtocol等效 不需要括号调用 var connection = thrift.createConnection(“localhost”, 9090, { transport : transport, protocol : protocol }); connection最后的选项如果没有的话默认是transport为buffer,protocol为binary 如果服务器为TFramedTransport,选项要传递{transport:thrift.TFramedTransport}
node.js 与C++通信的一个demo
协议文件 add.thrift struct AddReq { 1: i32 x; 2: i32 y; 3: i32 p; }
struct AddResp { 1: i32 z; }
service AddServer { AddResp Add(1: AddReq req); } 服务器 #include <iostream> #include <thrift/concurrency/PosixThreadFactory.h> #include <thrift/concurrency/ThreadManager.h> #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TNonblockingServer.h> #include <thrift/server/TThreadPoolServer.h> #include <thrift/transport/TServerSocket.h> #include <thrift/transport/TTransportUtils.h> #include “thrift_test/protocol/AddServer.h”
using ::apache::thrift::TProcessor; using ::apache::thrift::concurrency::ThreadManager; using ::apache::thrift::concurrency::PosixThreadFactory; using ::apache::thrift::transport::TProtocolFactory; using ::apache::thrift::protocol::TBinaryProtocolFactory; using ::apache::thrift::server::TNonblockingServer; using namespace std; using ::boost::shared_ptr;
class AddServer: public AddServerIf { public: virtual void Add(AddResp& _return, const AddReq& req) { cout<<“set p”<<req.p<<endl; _return.z = req.x + req.y; } };
int main() { try{ shared_ptr<AddServer> handler(new AddServer()); shared_ptr<TProcessor> processor(new AddServerProcessor(handler)); shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(32);
shared_ptr<PosixThreadFactory> threadFactory =
shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
TNonblockingServer server(
processor, protocolFactory, 9876, threadManager);
server.serve();
} catch (const std::exception& e) { std::cerr << "exception: " << e.what() << “\n”; } } node.js客户端 var thrift = require(‘thrift’); var AddServer = require(’./gen-nodejs/AddServer’); var ttypes = require(’./gen-nodejs/add_types’); var assert= require(‘assert’);
var connection = thrift.createConnection(“localhost”, 9876, {transport:thrift.TFramedTransport});
connection.on(‘error’, function(err) { //console.log(“connect error”); throw new Error(“connection error”); //assert(false, err); });
var client = thrift.createClient(AddServer, connection);
try { req= new ttypes.AddReq({x:1,y:2,p:3}); console.log(req.x); console.log(req.y); console.log(req.p); client.Add(req,function(err, resp) { console.log(resp.z); connection.end(); }); } catch(e) { console.log(e); console.log(“bye”); };