HelloWood

Thrift 中的 Protocol

2021-01-31

Thrift 中的 Protocol

TProtocol 是 Thrift 中协议的抽象类,定义了数据序列化和反序列化的接口

thrift-java-source-class-protocol.png

属性

TProtocol 中有 TTransport类型的属性trans_,用于与底层的传输层进行数据交互

方法

TProtocol 中的方法可以分为两类,分别用于写入和读取各种类型
其中 MessageStruct, Field,Map,List,Set 等类型会有开始和结束标志,一些还会写入或读取名称、序号等信息;可以参考 Thrift Protocol Structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* 写入
*/
public abstract void writeMessageBegin(TMessage message) throws TException;
public abstract void writeMessageEnd() throws TException;
public abstract void writeStructBegin(TStruct struct) throws TException;
public abstract void writeStructEnd() throws TException;
public abstract void writeFieldBegin(TField field) throws TException;
public abstract void writeFieldEnd() throws TException;
public abstract void writeFieldStop() throws TException;
public abstract void writeMapBegin(TMap map) throws TException;
public abstract void writeMapEnd() throws TException;
public abstract void writeListBegin(TList list) throws TException;
public abstract void writeListEnd() throws TException;
public abstract void writeSetBegin(TSet set) throws TException;
public abstract void writeSetEnd() throws TException;
public abstract void writeBool(boolean b) throws TException;
public abstract void writeByte(byte b) throws TException;
public abstract void writeI16(short i16) throws TException;
public abstract void writeI32(int i32) throws TException;
public abstract void writeI64(long i64) throws TException;
public abstract void writeDouble(double dub) throws TException;
public abstract void writeString(String str) throws TException;
public abstract void writeBinary(ByteBuffer buf) throws TException;
/**
* 读取
*/
public abstract TMessage readMessageBegin() throws TException;
public abstract void readMessageEnd() throws TException;
public abstract TStruct readStructBegin() throws TException;
public abstract void readStructEnd() throws TException;
public abstract TField readFieldBegin() throws TException;
public abstract void readFieldEnd() throws TException;
public abstract TMap readMapBegin() throws TException;
public abstract void readMapEnd() throws TException;
public abstract TList readListBegin() throws TException;
public abstract void readListEnd() throws TException;
public abstract TSet readSetBegin() throws TException;
public abstract void readSetEnd() throws TException;
public abstract boolean readBool() throws TException;
public abstract byte readByte() throws TException;
public abstract short readI16() throws TException;
public abstract int readI32() throws TException;
public abstract long readI64() throws TException;
public abstract double readDouble() throws TException;
public abstract String readString() throws TException;
public abstract ByteBuffer readBinary() throws TException;

实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void writeMessageBegin(TMessage message) throws TException {
if (strictWrite_) {
// 写入版本
int version = VERSION_1 | message.type;
writeI32(version);
// 被调用方法
writeString(message.name);
// 请求序号
writeI32(message.seqid);
} else {
writeString(message.name);
writeByte(message.type);
writeI32(message.seqid);
}
}
1
2
3
4
5
6
public void writeMessageBegin(TMessage message) throws TException {
writeByteDirect(PROTOCOL_ID);
writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
writeVarint32(message.seqid);
writeString(message.name);
}
  • TTupleProtocol:继承了 TCompactProtocol 类,Scheme 使用 TupleScheme,表示使用写消息体的方式序列化和反序列化,而不是 StandardScheme 使用消息头和消息体的方式序列化和反序列化
1
2
3
4
5
6
public void writeBitSet(BitSet bs, int vectorWidth) throws TException {
byte[] bytes = toByteArray(bs, vectorWidth);
for (byte b : bytes) {
writeByte(b);
}
}
  • TJSONProtocol:将消息序列化为 JSON,可以用于泛化调用的场景下
1
2
3
4
5
6
7
8
9
public void writeMessageBegin(TMessage message) throws TException {
resetContext(); // THRIFT-3743
writeJSONArrayStart();
writeJSONInteger(VERSION);
byte[] b = message.name.getBytes(StandardCharsets.UTF_8);
writeJSONString(b);
writeJSONInteger(message.type);
writeJSONInteger(message.seqid);
}
  • TSimpleJSONProtocol: 将消息以 JSON 格式输出,没有实现读取,用于脚本语言
1
2
3
4
5
6
7
8
public void writeMessageBegin(TMessage message) throws TException {
resetWriteContext(); // THRIFT-3743
trans_.write(LBRACKET);
pushWriteContext(new ListContext());
writeString(message.name);
writeByte(message.type);
writeI32(message.seqid);
}
  • TProtocolDecorator:抽象实现,会将所有的操作都转发给被代理的类实现
1
2
3
public void writeMessageBegin(TMessage tMessage) throws TException {
concreteProtocol.writeMessageBegin(tMessage);
}
  • TMultiplexedProtocolTProtocolDecorator 的实现类,在消息头部写入了服务的名称,会被 Server 端解析;用于有多个服务的 Server;其他的类型写入和读取由被代理的协议实现
1
2
3
4
5
6
7
8
9
10
11
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);
}
}
  • StoredMessageProtocolTProtocolDecorator 的实现类,代理其他协议,通常用于 Server 端,只获取请求头,具体的读取由被代理的协议实现
1
2
3
public TMessage readMessageBegin() throws TException {
return messageBegin;
}
Tags: Thrift