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

前言

        这一章我们来看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如何发送数据的流程,这些问题在下一章都会一一详述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值