如何指定非默认的Thrift协议和传输

时间:2016-02-05 17:29:31

标签: thrift idl

我已阅读official Apache Thrift docs。我读过优秀的Thrift By Example Docs。我甚至读过更优秀的Thrift: The Missing Guide

无处我可以弄清楚如何指定TCompactProtocol超过默认值(TBinaryProtocol)。或者说,TFramedSocket超过默认值(TSocket)。

有人可以在这里详细说明吗?

1 个答案:

答案 0 :(得分:1)

Thrift中的协议描述了如何将实际数据位写入/读取底层存储介质的格式。通常只需要一个这样的东西,不需要堆叠它们,因为您只需要一个物理布局来序列化数据。

相比之下,设计堆叠的是所谓的分层传输"。传输在较低的抽象级别上运行。典型的例子是TBufferedTransport/test/yourlanguage。分层传输为字节流添加功能,例如添加帧大小,缓冲数据或提供多路复用功能。从技术上讲,它们位于协议和底层传输之间。它实际上向/从存储介质(例如Socket)写入/读取字节。

因此,如果您需要将转换更改为字节,则需要编写另一个协议。每当需要额外的存储介质时,请编写端点传输。如果字节只应在序列化/反序列化过程之间进行操作,则表示要添加新的压缩算法" Schrippe"让BrotliZopfli看起来像旧面包(双关语非常有意),写一个分层的传输。

如何将所有内容堆叠在一起的一个很好的示例可以在Thrift Test Suite的语言相关实现中找到(在 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; 下有一些例外)。测试套件旨在测试各种组合。如果您已完成本教程,我建议您查看该代码,因为它解释了client endserver end的许多高级功能。

举个例子,这是相关部分from the C++ Test Client,其中设置了所有选定的组件:

@{ }