如何在 Apache Thrift 中切换传输协议
How to switch transport protocols in Apache Thrift
Apache Thrift netstack 巧妙地解释了传输协议可以是原始 TCP、HTTP 等。但是我找不到合适的文档来描述如何在底层传输协议的使用之间切换,也许我在这里遗漏了一些东西。
此外,还有一个小的跟进问题,正如我在 ubuntu 系统 (./configure
) 上构建 Thrift 之前配置的那样,我看到以下内容:
C++ Library:
Build TZlibTransport ...... : yes
Build TNonblockingServer .. : yes
Build TQTcpServer (Qt4) .... : no
Build TQTcpServer (Qt5) .... : no
考虑到我想使用 TCP 传输协议,我是否应该担心 TQTcpServer
未配置为构建?
我是 Thrift 的新手,请原谅我缺乏更好地构建问题的经验。
Thrift 具有端点传输、分层传输和协议的概念,这些概念相互堆叠以形成具体的实现。 tutorial说明了基本原理(这是C++版本):
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);
如果您需要切换传输,理论上您只需删除 TSocket
线并插入您选择的另一种传输。在实践中,它可能有一些更微妙的地方,但这是基本的想法。 test suite code 可以作为如何在实践中做到这一点的一个很好的例子:
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("[=11=]", 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;
}
这又是 C++,而且只是客户端。还有一个 counterpart for the server end 非常相似。
Apache Thrift netstack 巧妙地解释了传输协议可以是原始 TCP、HTTP 等。但是我找不到合适的文档来描述如何在底层传输协议的使用之间切换,也许我在这里遗漏了一些东西。
此外,还有一个小的跟进问题,正如我在 ubuntu 系统 (./configure
) 上构建 Thrift 之前配置的那样,我看到以下内容:
C++ Library:
Build TZlibTransport ...... : yes
Build TNonblockingServer .. : yes
Build TQTcpServer (Qt4) .... : no
Build TQTcpServer (Qt5) .... : no
考虑到我想使用 TCP 传输协议,我是否应该担心 TQTcpServer
未配置为构建?
我是 Thrift 的新手,请原谅我缺乏更好地构建问题的经验。
Thrift 具有端点传输、分层传输和协议的概念,这些概念相互堆叠以形成具体的实现。 tutorial说明了基本原理(这是C++版本):
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);
如果您需要切换传输,理论上您只需删除 TSocket
线并插入您选择的另一种传输。在实践中,它可能有一些更微妙的地方,但这是基本的想法。 test suite code 可以作为如何在实践中做到这一点的一个很好的例子:
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("[=11=]", 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;
}
这又是 C++,而且只是客户端。还有一个 counterpart for the server end 非常相似。