java - 尝试使用 thrift 的 TFileTransport 和 TFileProcessor 让 Python 客户端与 Java 服务器对话

标签 java python thrift thrift-protocol

我正在尝试使用 thrift 的 TFileTransport 包装一个要从 Python 调用的 Java 类。我尝试使用两种协议(protocol) TJSON 和 TBinary,但我一直收到此异常

org.apache.thrift.transport.TTransportException: FileTransport error: bad event size
    at org.apache.thrift.transport.TFileTransport.readEvent(TFileTransport.java:327)
    at org.apache.thrift.transport.TFileTransport.read(TFileTransport.java:468)
    at org.apache.thrift.transport.TFileTransport.readAll(TFileTransport.java:439)
    at org.apache.thrift.protocol.TJSONProtocol$LookaheadReader.read(TJSONProtocol.java:263)
    at org.apache.thrift.protocol.TJSONProtocol.readJSONSyntaxChar(TJSONProtocol.java:320)
    at org.apache.thrift.protocol.TJSONProtocol.readJSONArrayStart(TJSONProtocol.java:784)
    at org.apache.thrift.protocol.TJSONProtocol.readMessageBegin(TJSONProtocol.java:795)
    at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:27)
    at org.apache.thrift.transport.TFileProcessor.processUntil(TFileProcessor.java:69)
    at org.apache.thrift.transport.TFileProcessor.processChunk(TFileProcessor.java:102)
    at org.apache.thrift.transport.TFileProcessor.processChunk(TFileProcessor.java:111)
    at org.apache.thrift.transport.TFileProcessor.processChunk(TFileProcessor.java:118)
    at com.netflix.suro.client.SendToPyServer.startThriftServer(SendToPyServer.java:51)
    at com.netflix.suro.client.SendToPyServer.main(SendToPyServer.java:67)

这是我的 Python 客户端的样子:

 def __init__(self):
        self.outFile=open("../../ThriftFile.in","a")
        self.transport = TTransport.TFileObjectTransport(self.outFile)
        self.protocol = TJSONProtocol.TJSONProtocol(self.transport)
        self.client = sendPyInterface.Client(self.protocol)
        self.transport.open()

    def send(self,routingKey, message):
        self.transport.write(pickle.dumps(self.client.send_send(routingKey, message))) 


    def configClient(self,configurationDict):       
        self.transport.write(pickle.dumps(self.client.send_ClientConfig(configurationDict)))    

if __name__ == "__main__":
    SuroClient=SuroPyClient()
    configurationDict={"ClientConfig.LB_TYPE":"static","ClientConfig.LB_SERVER":"localhost:7101"}
    SuroClient.configClient(configurationDict)
    SuroClient.send("routingKey", "testMessage")

这是我的服务器:

public static void startThriftServer(SendPyInterface.Processor processor) {
            try {
                File input = new File("src/main/java/com/netflix/suro/client/ThriftFile.in");
                if(!input.exists()){
                    input.createNewFile();
                }

                File output = new File("src/main/java/com/netflix/suro/client/ThriftFile.out");
                if(!output.exists()){
                    output.createNewFile();
                }

                TFileTransport inputFileTransport = new TFileTransport(input.getAbsolutePath(), true);
                TFileTransport outputFileTransport = new TFileTransport(output.getAbsolutePath(), false);
                System.out.println(input.getAbsolutePath());
                System.out.println(input.length());

                inputFileTransport.open();
                outputFileTransport.open();
                System.out.println(inputFileTransport.getBytesRemainingInBuffer());
                inputFileTransport.setTailPolicy(tailPolicy.WAIT_FOREVER);
                System.out.println("Wait ...");
                System.out.println(inputFileTransport.getBuffer());
                TFileProcessor fProcessor = 
                        new TFileProcessor(processor, new TJSONProtocol.Factory(), inputFileTransport, outputFileTransport);
                try {
                    fProcessor.processChunk();
                } catch (TTransportException e) {
                    e.printStackTrace();
                }


                System.out.println("File Thrift service started ...");
            } catch (Exception e) {
                e.printStackTrace();
            }

我遵循了这个线程中的示例: Example on how to use TFileTransport in Thrift (Client/Server)

来自这篇文章: http://theprogrammersguideto.com/thrift/blog/code/chapter-3-moving-bytes-with-transports/

最佳答案

根据docs in the old Thrift wiki ,Java和C++的TFileTransport其实是一个framed transport ,它会在数据之前写入一个额外的 4 字节 header 。似乎这里的名称有点误导。

相比之下,使用的 Python TFileObjectTransport 只是一个简单的包装器。这意味着传输不兼容,因此出现错误消息。

因此 TFileTransport 应该与 Java 一起使用 TSimpleFileTransport

关于java - 尝试使用 thrift 的 TFileTransport 和 TFileProcessor 让 Python 客户端与 Java 服务器对话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24274239/

相关文章:

python - argparse:将参数与另一个参数相关联

python - GIS/Gdal/OSGeos 在 Windows 上的 django 中导入错误

versioning - Thrift 文件 (api) 版本控制的最佳实践是什么?

php - 在 PHP 中通过 Hive/Thrift 查询数据库不起作用

java - 从 Seam 电子邮件生成绝对 URL

java - Android Studio 在 findViewById 上崩溃

java - 替代 Java 8 中的 Thread.stop()?

java - 使用来自循环方法的列表内容更新列表

python - "[Errno 13] Permission denied"仅在 Ubuntu 服务器上尝试更新/更改文档时

node.js - 将 Apache Thrift 与 Node.js 一起使用