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);
}
}
public void writeI32(int i32) throws TException {
i32out[0] = (byte)(0xff & (i32 >> 24));
i32out[1] = (byte)(0xff & (i32 >> 16));
i32out[2] = (byte)(0xff & (i32 >> 8));
i32out[3] = (byte)(0xff & (i32));
//这一段代码就说明真正进行网络I/O读写的是TTransport
trans_.write(i32out, 0, 4);
}
TProtocol中封装了每一个数据类型读和写,这里的读写是针对网络I/O的读写,真正的网络读写的是TTransport,它主要处理数据的,如对数据格式的调整。
TProtocol是一个抽象方法,为了不让外部实现这个类,所以它私有化了构造方法。
/**
* Prevent direct instantiation
*/
@SuppressWarnings("unused")
private TProtocol() {}
同时它又提供了能够让父类继承的构造函数。这个构造方法传递了一个参数,TTransport.
/**
* Constructor
*/
protected TProtocol(TTransport trans) {
trans_ = trans;
}
从上面知道,TProtocol这个协议它只是处理数据的,其真正对网络进行读写的是TTransport,所以它维护了一个TTransport 例如TBinaryProtocol
/**
* Transport
*/
protected TTransport trans_;
/**
* Transport accessor
*/
public TTransport getTransport() {
return trans_;
}
TProtocol定义了各种数据类型的写方法
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;
我们可以从上面的抽象方法中可以看出,只要thrift文件支持的数据类型,都有与之相对应的写方法。在上面的方法中,
writeMessageBegin(TMessage message)
可以看到它的参数时TMessage,在thrift中客户端和服务端通信的媒介被封装成了TMessage,TMessage中主要有三个属性
public final String name;
public final byte type;
public final int seqid;
public TMessage() {
this("", TType.STOP, 0);
}
public TMessage(String n, byte t, int s) {
name = n;
type = t;
seqid = s;
}
name:功能方法的名称,其实就是thrift文件中定义的服务方法名。如果使用TMessage的无参方法,则name默认为“”
type:从TMessageType获取的,如果使用TMessage的无参方法,则设置为TType.STOP
public final class TMessageType {
public static final byte CALL = 1;
public static final byte REPLY = 2;
public static final byte EXCEPTION = 3;
public static final byte ONEWAY = 4;
}
seqid:用来标示客户端的。
上面的写方法,有Begin和End,所以
public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
getUser_args args = new getUser_args();
args.write(prot);
prot.writeMessageEnd();
}
TProtocol同时也定义了各种数据类型的读方法
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;
thrift框架支持一下协议:
1)TBinaryProtocol :二进制格式
2)TCompactProtocol:压缩格式
3)TJSONProtocol:Json格式
4)TSimpleJSONProtocol:提供json只写协议
这些具体的协议中都定义了一个工厂。这些工厂都实现了TProtocolFactory这个接口,这个接口中有一个方法,就是获取具体的协议的
public interface TProtocolFactory extends Serializable {
public TProtocol getProtocol(TTransport trans);
}
依TBinaryProtocol为例,看看怎样从工厂中获取具体的协议的
public TProtocol getProtocol(TTransport trans) {
//首先创建一个TBinaryProtocol二进制协议对象
TBinaryProtocol proto = new TBinaryProtocol(trans, strictRead_, strictWrite_);
if (readLength_ != 0) {
proto.setReadLength(readLength_);
}
return proto;
}