如何在使用Apache Thrift时检测协议不匹配?

时间:2015-08-07 09:23:04

标签: thrift thrift-protocol

我正在运行一对客户端和服务器程序,在我的Mac上使用Apache Thrift进行通信。在我们的生产系统中,我们最终可能会遇到客户端使用TJSONProtocol并且服务器使用TBinaryProtocol进行序列化和反序列化的情况。

我知道这是一件可怕的事情。但我不确定如何预先检测到这一点。我尝试了一个不同协议的示例程序。我原本期待收到异常,但客户端卡在RPC调用上并且从未返回过。

使用TBinaryProtocol的服务器代码:

shared_ptr<SomethingHandler> handler(new SomethingHandler());
shared_ptr<TProcessor> processor(new SomethingProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();

使用TJSONProtocol的客户端代码:

boost::shared_ptr < TSocket > socket(new TSocket(argv[1], 9090));
boost::shared_ptr < TTransport > transport(new TBufferedTransport(socket));
boost::shared_ptr < TProtocol > protocol(new TJSONProtocol(transport));
transport->open();
std::cout<<"Transport open success"<<std::endl;
SomethingClient client(protocol);
std::cout<<"Create client success"<<std::endl;
try{
    std::cout<<"About to ping"<<std::endl;
    client.ping(argv[2]);
    std::cout<<"Ping success"<<std::endl;
    }catch(TException e){
    std::cout<<"Exception occurred:"<<e.what()<<std::endl;
}
transport->close();

在这个例子中,我永远不会打印Ping success。 有没有什么方法可以检测到这种不兼容性而不会卡住?

1 个答案:

答案 0 :(得分:4)

我怕你不能。根据定义,您需要在两端建立完全相同的协议/传输堆栈 1);其他任何东西都是无效的。

如果您需要不同的协议/传输堆栈,则需要设置适当数量的不同端点。

除了更高级别的堆栈上的通常机制之外,没有任何保护或检测。你卡住的原因很可能是对数据的误解,所以服务器可能只是等待更多的请求字节进入,你不发送。

1)该规则有一些例外情况,但这里并不重要。