您的位置:首页 > 编程语言 > PHP开发

4、thrift源码分析之_TProtocol协议

2014-05-29 09:55 495 查看
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);
}


  我们知道对于RPC框架,通信协议是重要的一环,对于thrift框架来说,thrift定义了一个协议的顶层接口TProtocol,其实TProtocol是一个抽象类并且它内部也维护了一个TTransport,这个协议的作用就是对传输数据格式的封装,实现不同的协议来适合不同场景下的数据传输。

 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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  thrift TProtocol