2016-02-05 32 views

回答

1

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

相比之下,设计成堆叠的是所谓的“分层运输”。运输工作的抽象程度较低。非常典型的例子是TFramedTransportTBufferedTransport。分层传输为字节流增加功能,例如添加帧大小,缓存数据或提供多路复用功能。从技术上讲,它们位于协议和实际向/从存储介质(例如Socket)写/读字节的底层“端点传输”之间。

因此,如果您需要更改从字节到字节的转换,则需要编写另一个协议。无论何时需要额外的存储介质,写入端点传输。如果字节只能在序列化/反序列化过程之间进行操作,比如说你想添加新的压缩算法“Schrippe”,让BrotliZopfli看起来像旧面包(双语非常有意义),写一个分层传输。

一个很好的例子说明如何将所有东西堆叠在一起可以在Thrift Test Suite的语言相关实现中找到(除了位于/test/yourlanguage下的少数例外)。该测试套件旨在测试各种组合。如果您已完成本教程,我建议查看该代码,因为它解释了client endserver 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;