简体   繁体   中英

Apache Thrift for just processing, not server

I hope I don't have misunderstood the Thrift concept, but what I see from (example) questions like this , this framework is composed by different modular layers that can be enabled or disabled.

I'm mostly interesed in the "IDL part" of Thrift, so that I can create a common interface between my C++ code and an external Javascript application. I would like to call C++ functions using JS, with Binary data transmission, and I've already used the compiler for this.

But both my C++ (the server) and JS (client) application already exchange data using a C++ Webserver with Websockets support, it is not provided by Thrift .

So I was thinking to setup the following items:

  • In JS (already done):

    • TWebSocketTransport to send data to my "Websocket server" (with host ws://xxx.xxx.xxx.xxx)
    • TBinaryProtocol to encapsulate the data (using this JS implementation )
    • The compiled Thrift JS library with the correspondent C++ functions to call (done with the JS compiler)
  • In C++ (partial):

    • TBinaryProtocol to encode/decode the data
    • A TProcessor with handler to get the data from the client and process it

For now, the client is already able to sent requests to my websocket server, I see receiving them in binary form and I just need Thrift to:

  1. Decode the input
  2. Call the appropriate C++ function
  3. Encode the output

My webserver will send the response to the client. So no "Thrift server" is needed here. I see there is the TProcessor->process() function, I'm trying to use it when I receive the binary data but it needs an in/out TProtocol. No problem here... but in order to create the TBinaryProtocol I also need a TTransport! If no Thrift server is expected... what Transport should I use?

I tried to set TTransport to NULL in TBinaryProtocol constructor, but once I use it it gives nullptr exception.

Code is something like:

Init:

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???));

When data arrives:

this->thriftInputProtocol->writeBinary(input); // exception here
this->thriftCommandProcessor->process(this->thriftInputProtocol, this->thriftOutputProtocol, NULL);
this->thriftOutputProtocol->readBinary(output);

My webserver will send the response to the client. So no "Thrift server" is needed here. I see there is the TProcessor->process() function, I'm trying to use it when I receive the binary data but it needs an in/out TProtocol. No problem here... but in order to create the TBinaryProtocol I also need a TTransport! If no Thrift server is expected... what Transport should I use?

The usual pattern is to store the bits somewhere and use that buffer or data stream as the input, same for the output. For certain languages there is a TStreamTransport available, for C++ the TBufferBase class looks promising to me.

I've managed to do it using the following components:

// 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM