Thrift源码系列----3.TProtocol层功能分析

来源:互联网 发布:windows桌面 编辑:程序博客网 时间:2024/05/21 11:21

前言

        这一章我们来看TProtocol提供了哪些方法,重点介绍方法的功能,不对每个方法的源码实现做细致的分析,由于这一章牵扯到了上一层方法的调用问题,会有些难以理解,更多细节会在下一章详述。

数据结构

        在Thrift中有一套规则,规定了如何将我们传入的对象转为自身可使用的参数,下面我们来看三个类。

        TField代表一个字段,无论该字段是一个对象还是基本字段,都用TField表示,源码:

public class TField {  public final String name;//此字段的名称  public final byte   type;//此字段的类型,取值见下面的TType源码  public final short  id;//该字段在所在对象中的排序,这与Thrift源文件中的序号是对应的,也是Thrift用于将网络中获取的数据映射为本地Java对象  public TField() {    this("", TType.STOP, (short)0);  }  public TField(String n, byte t, short i) {    name = n;    type = t;    id = i;  }  //后面方法省略,没什么作用}//字段是何种类型public final class TType {  public static final byte STOP   = 0;//字段已经完结,可以结束了  public static final byte VOID   = 1;//不用返回结果  public static final byte BOOL   = 2;//boolean字段  public static final byte BYTE   = 3;//byte字段  public static final byte DOUBLE = 4;//double字段  public static final byte I16    = 6;//16位编码字段  public static final byte I32    = 8;//32位编码字段  public static final byte I64    = 10;//64位编码字段  public static final byte STRING = 11;//string型字段  public static final byte STRUCT = 12;//对象型字段  public static final byte MAP    = 13;//map结构字段  public static final byte SET    = 14;//set结构字段  public static final byte LIST   = 15;//list结构字段  public static final byte ENUM   = 16;//enum结构字段}

        TStruct代表一个对象,当参数为一个对象时,用该结构来表示,源码:

public final class TStruct {  public final String name;//对象的 类名称,使客户端服务端知道如何将字节转为哪个类的对象  public TStruct() {    this("");  }  public TStruct(String n) {    name = n;  }}

        TMessage代表一条请求,在客户端数据前,必须先发送TMessage告诉服务端我们调用的是哪个方法,该条请求的类型,版本号。

public final class TMessage {  public final String name;//调用方法的名称  public final byte type;//该条message是代表什么类型的请求,详见TMessageType  public final int seqid;//Thrift版本号,用于校验  public TMessage() {    this("", TType.STOP, 0);  }  public TMessage(String n, byte t, int s) {    name = n;    type = t;    seqid = s;  }  @Override  public String toString() {    return "<TMessage name:'" + name + "' type: " + type + " seqid:" + seqid + ">";  }  @Override  public int hashCode() {    final int prime = 31;    int result = 1;    result = prime * result + ((name == null) ? 0 : name.hashCode());    result = prime * result + seqid;    result = prime * result + type;    return result;  }  @Override  public boolean equals(Object obj) {    if (this == obj)      return true;    if (obj == null)      return false;    if (getClass() != obj.getClass())      return false;    TMessage other = (TMessage) obj;    if (name == null) {      if (other.name != null)        return false;    } else if (!name.equals(other.name))      return false;    if (seqid != other.seqid)      return false;    if (type != other.type)      return false;    return true;  }}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;//不大清楚含义,用处较少}

TProtocol

        我们还是先看下协议层的父类TProtocol源码:

public abstract class TProtocol {  protected TTransport trans_;//是不是很熟悉,就是用于读写  @SuppressWarnings("unused")  private TProtocol() {}  protected TProtocol(TTransport trans) {    trans_ = trans;  }  public TTransport getTransport() {    return trans_;  }  /**   * 所有的写方法   */  //发送一条请求开始、结束时调用该方法  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;  //map结构开始结束方法  public abstract void writeMapBegin(TMap map) throws TException;  public abstract void writeMapEnd() throws TException;  //list开始结束方法  public abstract void writeListBegin(TList list) throws TException;  public abstract void writeListEnd() throws TException;  //set开始结束方法  public abstract void writeSetBegin(TSet set) throws TException;  public abstract void writeSetEnd() throws TException;  //基本类型及string写方法,上面的所有方法最终都会调下面这些基本方法来实现  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;  public void reset() {}  //该类这里先忽略,是关于对象与字节之间转换的  public Class<? extends IScheme> getScheme() {    return StandardScheme.class;  }}

        关于二进制协议 ,在实现时也只是将boolean、long等转为字节数组发送出去,有兴趣的可以看看下面链接:
        http://www.cnblogs.com/voipman/p/5125278.html
        http://blog.csdn.net/zdq0394123/article/details/6597332

总结

        本章看完大家可能还是一头雾水,虽然知道了方法的作用,但还是对于它的使用场景没有了解,主要因为牵扯到了Thrift如何发送数据的流程,这些问题在下一章都会一一详述。

0 0
原创粉丝点击