thrift-protocol
程序员文章站
2022-06-17 12:13:58
...
// Thrift 消息类型
public final class TMessageType {
public static final byte CALL = 1; // 调用远程方法,并且期待对方发送响应
public static final byte ONEWAY = 4; // 调用远程方法,不期待响应。即没有步骤3,4
public static final byte REPLY = 2; // 表明处理完成,响应正常返回
public static final byte EXCEPTION = 3; // 表明出理出错
}
// Thrift 支持的数据类型
public final class TType {
// 标识属性的结尾(即读到 STOP 表明后边没有属性了)
public static final byte STOP = 0;
public static final byte VOID = 1;
public static final byte BOOL = 2; // 对应于 java 中的 boolean
public static final byte BYTE = 3; // byte
public static final byte DOUBLE = 4; // double
public static final byte I16 = 6; // short
public static final byte I32 = 8; // int
public static final byte I64 = 10; // long
public static final byte STRING = 11; // String
// 类似于 C 语言中的结构体
public static final byte STRUCT = 12;
public static final byte MAP = 13;
public static final byte SET = 14;
public static final byte LIST = 15;
public static final byte ENUM = 16;
}
// thrift 消息头(方法名称:方法类型:方法序号)
public final class TMessage {
public final String name;
public final byte type;
public final int seqid;
// ...
}
// 字段消息头:字段名称-字段类型-字段序号
public class TField {
public final String name;
public final byte type;
public final short id;
}
// List 消息头 元素类型-元素个数
public final class TList {
public final byte elemType;
public final int size;
}
// Map 消息头 键类型-值类型-元素个数
public final class TMap {
public final byte keyType;
public final byte valueType;
public final int size;
}
// Set 消息头 元素类型-元素个数
public final class TSet {
public final byte elemType;
public final int size;
}
// Struct 消息头: XXX_args XXX_result 的消息头说明
public final class TStruct {
public final String name;
}
TMessage 的 equals 方法比较了 name,而 TField 中没有,想想为什么?
因为在 thrift 中,使用参数类型和索引,区分是哪一个参数。而 TMessage 描述的方法调用的元数据。
string sayBye(1: optional string name, 2: optional i32 age)
TField 的 id 属性,表示是参数相对位置的索引,如下方的 1,2。
struct Request {
1: required i32 age;
2: required string name;
}
id 为何是 short 类型?引申为 Java 中参数列表支持多少个参数。
https://zhuanlan.zhihu.com/p/44086976
java 中参数列表最大支持 255 个单位长度。
public abstract class TProtocolDecorator extends TProtocol {
private final TProtocol concreteProtocol;
public TProtocolDecorator(TProtocol protocol) {
super(protocol.getTransport());
concreteProtocol = protocol;
}
// ...
}
TProtocolDecorator采用装饰者模式,将调用委托给内部的 concreteProtocol。
public class TMultiplexedProtocol extends TProtocolDecorator {
public static final String SEPARATOR = ":";
private final String SERVICE_NAME;
public TMultiplexedProtocol(TProtocol protocol, String serviceName) {
super(protocol);
SERVICE_NAME = serviceName;
}
@Override
public void writeMessageBegin(TMessage tMessage) throws TException {
if (tMessage.type == TMessageType.CALL || tMessage.type == TMessageType.ONEWAY) {
super.writeMessageBegin(new TMessage(
SERVICE_NAME + SEPARATOR + tMessage.name,
tMessage.type,
tMessage.seqid
));
} else {
super.writeMessageBegin(tMessage);
}
}
}
使用
TSocket transport = new TSocket("localhost", 9090);
transport.open();
TBinaryProtocol protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
Calculator.Client service = new Calculator.Client(mp);
TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
WeatherReport.Client service2 = new WeatherReport.Client(mp2);
System.out.println(service.add(2,2));
System.out.println(service2.getTemperature());
上一篇: Thrift初学
下一篇: IIS的unlink()没反应解决办法
推荐阅读