我已閱讀official Apache Thrift docs。我讀過優秀的Thrift By Example Docs。我甚至讀過更優秀的Thrift: The Missing Guide。如何指定非默認的Thrift協議和傳輸
不知道我可以弄清楚如何在默認值(TBinaryProtocol
)上指定,比如TCompactProtocol
。或者,比方說TFramedSocket
超過默認值(TSocket
)。
有人可以在這裏詳細說明嗎?
我已閱讀official Apache Thrift docs。我讀過優秀的Thrift By Example Docs。我甚至讀過更優秀的Thrift: The Missing Guide。如何指定非默認的Thrift協議和傳輸
不知道我可以弄清楚如何在默認值(TBinaryProtocol
)上指定,比如TCompactProtocol
。或者,比方說TFramedSocket
超過默認值(TSocket
)。
有人可以在這裏詳細說明嗎?
Thrift中的協議描述了實際數據位如何寫入底層存儲介質或從底層存儲介質讀取數據的格式。通常只需要一個這樣的東西,堆疊它們不是必需的,因爲您只需要一個物理佈局來序列化數據。
相比之下,設計成堆疊的是所謂的「分層運輸」。運輸工作的抽象程度較低。非常典型的例子是TFramedTransport
和TBufferedTransport
。分層傳輸爲字節流增加功能,例如添加幀大小,緩存數據或提供多路複用功能。從技術上講,它們位於協議和實際向/從存儲介質(例如Socket)寫/讀字節的底層「端點傳輸」之間。
因此,如果您需要更改從字節到字節的轉換,則需要編寫另一個協議。無論何時需要額外的存儲介質,寫入端點傳輸。如果字節只能在序列化/反序列化過程之間進行操作,比如說你想添加新的壓縮算法「Schrippe」,讓Brotli和Zopfli看起來像舊麪包(雙語非常有意義),寫一個分層傳輸。
一個很好的例子說明如何將所有東西堆疊在一起可以在Thrift Test Suite的語言相關實現中找到(除了位於/test/yourlanguage
下的少數例外)。該測試套件旨在測試各種組合。如果您已完成本教程,我建議查看該代碼,因爲它解釋了client end和server end的許多高級功能。
只是作爲一個例子,這是在相關部分from the C++ Test Client其中所有選定的組件都設置:
boost::shared_ptr<TTransport> transport;
boost::shared_ptr<TProtocol> protocol;
boost::shared_ptr<TSocket> socket;
boost::shared_ptr<TSSLSocketFactory> factory;
if (ssl) {
factory = boost::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
factory->loadTrustedCertificates((dir_path + "../keys/CA.pem").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;
}
if (protocol_type.compare("json") == 0) {
boost::shared_ptr<TProtocol> jsonProtocol(new TJSONProtocol(transport));
protocol = jsonProtocol;
} else if (protocol_type.compare("compact") == 0) {
boost::shared_ptr<TProtocol> compactProtocol(new TCompactProtocol(transport));
protocol = compactProtocol;
} else if (protocol_type == "header") {
boost::shared_ptr<TProtocol> headerProtocol(new THeaderProtocol(transport));
protocol = headerProtocol;
} else {
boost::shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol(transport));
protocol = binaryProtocol;
}
// Connection info
cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
if (abstract_namespace) {
cout << '@';
}
cout << domain_socket;
if (port != 0) {
cout << host << ":" << port;
}
cout << endl;