0

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);
TheUnexpected
  • 3,077
  • 6
  • 32
  • 62

2 Answers2

2

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);
}
TheUnexpected
  • 3,077
  • 6
  • 32
  • 62
1

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.

JensG
  • 13,148
  • 4
  • 45
  • 55