gpt4 book ai didi

java - Thrift Java 客户端无法正确处理 union

转载 作者:可可西里 更新时间:2023-11-01 16:17:14 26 4
gpt4 key购买 nike

死的简单 Thrift 联盟的例子。环境:最新的thrift,cpp作为服务器,java作为客户端mytest.thrift:

namespace java com.wilbeibi.thrift

union Value {
1: i16 i16_v,
2: string str_v,
}

struct Box {
1: Value value;
}

service MyTest {
Box echoUnion(1: i32 number);
}

C++ 服务器代码:

#include "MyTest.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

class MyTestHandler : virtual public MyTestIf {
public:
MyTestHandler() {
// Your initialization goes here
}

void echoUnion(Box& _return, const int32_t number) {
// Your implementation goes here
printf("Into echoUnion\n");
if (number % 2 == 0) {
Value v;
v.__set_i16_v(100);
v.__isset.i16_v = true;
_return.__set_value(v);
printf("Even number set int32\n");
} else {
Value v;
v.__set_str_v("String value");
v.__isset.str_v = true;
_return.__set_value(v);
printf("Odd number set string\n");
}
printf("echoUnion\n");
}

};

int main(int argc, char **argv) {
int port = 9090;
shared_ptr<MyTestHandler> handler(new MyTestHandler());
shared_ptr<TProcessor> processor(new MyTestProcessor(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);
printf("Server is running on %d\n", port);
server.serve();
return 0;
}

java 客户端代码:

// some imports here
public class Client {
public void startClient() {
TTransport transport;
try {
transport = new TSocket("localhost", 9090);
TProtocol protocol = new TBinaryProtocol(transport);
MyTest.Client client = new MyTest.Client(protocol);
transport.open();
Box box = client.echoUnion(1);
System.out.println(box.toString());

Box box2 = client.echoUnion(2);
System.out.println(box2.toString());

transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.startClient();
}
}

不知何故,java 客户端无法正确打印出字符串。 (我也写了一个 python 客户端,但这似乎可行)

要点的完整代码在这里:thrift file, c++ and java code

最佳答案

其实你在观察THRIFT-1833导致编译器为 union 类型生成无效 C++ 代码的错误。

在您的情况下,服务器写入 union 类型的两个字段,而客户端始终只读取第一个 - i16_v(剩余字节仍驻留在缓冲区中)。所以第二次读取永远不会结束,因为它在缓冲区中发现了一些意外数据。

您可以使用struct 代替union 并手动维护单字段逻辑。或者你可以贡献/等到错误被修复。

最后一个选项是对错误生成的 C++ 源代码应用补丁,如下所示:

--- mytest_types.cpp    2016-02-26 20:02:57.210652969 +0300
+++ mytest_types.cpp.old 2016-02-26 20:02:39.650652742 +0300
@@ -80,13 +80,17 @@
apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
xfer += oprot->writeStructBegin("Value");

- xfer += oprot->writeFieldBegin("i16_v", ::apache::thrift::protocol::T_I16, 1);
- xfer += oprot->writeI16(this->i16_v);
- xfer += oprot->writeFieldEnd();
+ if (this->__isset.i16_v) {
+ xfer += oprot->writeFieldBegin("i16_v", ::apache::thrift::protocol::T_I16, 1);
+ xfer += oprot->writeI16(this->i16_v);
+ xfer += oprot->writeFieldEnd();
+ }

- xfer += oprot->writeFieldBegin("str_v", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->str_v);
- xfer += oprot->writeFieldEnd();
+ if (this->__isset.str_v) {
+ xfer += oprot->writeFieldBegin("str_v", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeString(this->str_v);
+ xfer += oprot->writeFieldEnd();
+ }

关于java - Thrift Java 客户端无法正确处理 union ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35444656/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com