The Apache Thrift netstack neatly explains that the transport protocol can be raw TCP, HTTP, etc. I however could not find a proper documentation which describes how I can switch between use of transport protocols underneath, maybe I am missing something here.
Also, a small follow up question, as I configure before building Thrift on my ubuntu system (./configure
), I see the following:
C++ Library:
Build TZlibTransport ...... : yes
Build TNonblockingServer .. : yes
Build TQTcpServer (Qt4) .... : no
Build TQTcpServer (Qt5) .... : no
Should I be alarmed that the TQTcpServer
was not configured to be built, given that I want to use a TCP transport protocol?
I am new to Thrift, excuse my lack of experience for framing the question better.
Thrift has the concept of endpoint transports, layered transports and protocols stacked onto each other to form a concrete implementation. The tutorial shows the basic principle (this is the C++ version):
boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
CalculatorClient client(protocol);
If you need to switch transports, in theory you simply remove the TSocket
line and plug in another transport of your choice. In practice, there may be some more subtleties to it, but that's the basic idea. The test suite code can serve as an quite good example how to do this in practice:
if (ssl) {
factory = boost::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
factory->loadTrustedCertificates(pemPath.c_str());
factory->authenticate(true);
socket = factory->createSocket(host, port);
} else {
if (domain_socket != "") {
if (abstract_namespace) {
std::string abstract_socket("\0", 1);
abstract_socket += domain_socket;
socket = boost::shared_ptr<TSocket>(new TSocket(abstract_socket));
} else {
socket = boost::shared_ptr<TSocket>(new TSocket(domain_socket));
}
port = 0;
} else {
socket = boost::shared_ptr<TSocket>(new TSocket(host, port));
}
}
if (transport_type.compare("http") == 0) {
boost::shared_ptr<TTransport> httpSocket(new THttpClient(socket, host, "/service"));
transport = httpSocket;
} else if (transport_type.compare("framed") == 0) {
boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
transport = framedSocket;
} else {
boost::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
transport = bufferedSocket;
}
This is again C++ and only the client side. There's also a counterpart for the server end that works very similar.