Apache Thrift 仅用于处理,而不是服务器
Posted
技术标签:
【中文标题】Apache Thrift 仅用于处理,而不是服务器【英文标题】:Apache Thrift for just processing, not server 【发布时间】:2019-06-17 10:57:10 【问题描述】:我希望我没有误解 Thrift 的概念,但是我从(示例)questions like this 中看到,这个框架是由可以启用或禁用的不同模块化层组成的。
我最感兴趣的是 Thrift 的“IDL 部分”,这样我就可以在我的 C++ 代码和外部 javascript 应用程序之间创建一个通用接口。我想用JS调用C++函数,用二进制数据传输,我已经用过编译器了。
但我的 C++(服务器)和 JS(客户端)应用程序已经使用支持 Websockets 的 C++ Web 服务器交换数据,Thrift 不提供它。
所以我想设置以下项目:
在 JS 中(已经完成):
TWebSocketTransport 将数据发送到我的“Websocket 服务器”(主机为 ws://xxx.xxx.xxx.xxx) TBinaryProtocol 封装数据(使用这个JS implementation) 编译后的 Thrift JS 库和对应的 C++ 函数调用(用 JS 编译器完成)在 C++ 中(部分):
TBinaryProtocol 对数据进行编码/解码 带有处理程序的 TProcessor,用于从客户端获取数据并进行处理目前,客户端已经能够向我的 websocket 服务器发送请求,我看到以二进制形式接收它们,我只需要 Thrift 即可:
-
解码输入
调用相应的 C++ 函数
编码输出
我的网络服务器会将响应发送给客户端。所以这里不需要“Thrift 服务器”。我看到有 TProcessor->process() 函数,我在收到二进制数据时尝试使用它,但它需要一个输入/输出 TProtocol。没问题……但为了创建 TBinaryProtocol,我还需要一个 TTransport!如果不需要 Thrift 服务器...我应该使用什么传输?
我尝试在 TBinaryProtocol 构造函数中将 TTransport 设置为 NULL,但是一旦我使用它,它就会给出 nullptr 异常。
代码类似于:
初始化:
boost::shared_ptr<MySDKServiceHandler> handler(new MySDKServiceHandler());
thriftCommandProcessor = boost::shared_ptr<TProcessor>(new MySDKServiceProcessor(handler));
thriftInputProtocol = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(TTransport???));
thriftOutputProtocol = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(TTransport???));
当数据到达时:
this->thriftInputProtocol->writeBinary(input); // exception here
this->thriftCommandProcessor->process(this->thriftInputProtocol, this->thriftOutputProtocol, NULL);
this->thriftOutputProtocol->readBinary(output);
【问题讨论】:
【参考方案1】:我已经设法使用以下组件来做到这一点:
// create the Processor using my compiled Thrift class (from IDL)
boost::shared_ptr<MySDKServiceHandler> handler(new MySDKServiceHandler());
thriftCommandProcessor = boost::shared_ptr<TProcessor>(new ThriftSDKServiceProcessor(handler));
// Transport is needed, I use the TMemoryBuffer so everything is kept in local memory
boost::shared_ptr<TTransport> transport(new apache::thrift::transport::TMemoryBuffer());
// my client/server data is based on binary protocol. I pass the transport to it
thriftProtocol = boost::shared_ptr<TProtocol>(new TBinaryProtocol(transport, 0, 0, false, false));
/* .... when the message arrives through my webserver */
void parseMessage(const byte* input, const int input_size, byte*& output, int& output_size)
// get the transports to write and read Thrift data
boost::shared_ptr<TTransport> iTr = this->thriftProtocol->getInputTransport();
boost::shared_ptr<TTransport> oTr = this->thriftProtocol->getOutputTransport();
// "transmit" my data to Thrift
iTr->write(input, input_size);
iTr->flush();
// make the Thrift work using the Processor
this->thriftCommandProcessor->process(this->thriftProtocol, NULL);
// the output transport (oTr) contains the called procedure result
output = new byte[MAX_SDK_WS_REPLYSIZE];
output_size = oTr->read(output, MAX_SDK_WS_REPLYSIZE);
【讨论】:
【参考方案2】:我的网络服务器会将响应发送给客户端。所以这里不需要“Thrift 服务器”。我看到有 TProcessor->process() 函数,我在收到二进制数据时尝试使用它,但它需要一个输入/输出 TProtocol。没问题……但为了创建 TBinaryProtocol,我还需要一个 TTransport!如果不需要 Thrift 服务器...我应该使用什么传输?
通常的模式是将位存储在某处并将该缓冲区或数据流用作输入,对于输出也是如此。对于某些语言,有一个 TStreamTransport
可用,对于 C++,TBufferBase
类对我来说很有希望。
【讨论】:
TMemoryBuffer 怎么样? 试试看。我不得不承认我自己并不经常使用 C++ 绑定。您也可以在其中一个邮件列表中提问,周围有更好的 C++ 专家。以上是关于Apache Thrift 仅用于处理,而不是服务器的主要内容,如果未能解决你的问题,请参考以下文章
Apache Thrift TSimpleServer 是不是丢弃请求?