thrift-protocol

在这里插入图片描述

// Thrift 消息类型
public final class TMessageType {
  public static final byte CALL  = 1; 		// 调用远程方法,并且期待对方发送响应
  public static final byte ONEWAY = 4; 	// 调用远程方法,不期待响应。即没有步骤3,4
  public static final byte REPLY = 2; 		// 表明处理完成,响应正常返回
  public static final byte EXCEPTION = 3; // 表明出理出错

}

// Thrift 支持的数据类型
public final class TType {
  // 标识属性的结尾(即读到 STOP 表明后边没有属性了)
  public static final byte STOP   = 0;
  
  public static final byte VOID   = 1;
  
  public static final byte BOOL   = 2;   // 对应于 java 中的 boolean
  public static final byte BYTE   = 3;   // byte
  public static final byte DOUBLE = 4;   // double
  public static final byte I16    = 6;   // short
  public static final byte I32    = 8;   // int
  public static final byte I64    = 10;  // long 
  public static final byte STRING = 11;  // String
  // 类似于 C 语言中的结构体
  public static final byte STRUCT = 12;
  
  public static final byte MAP    = 13;
  public static final byte SET    = 14;
  public static final byte LIST   = 15;
  public static final byte ENUM   = 16;
}

// thrift 消息头(方法名称:方法类型:方法序号)
public final class TMessage {
  public final String name;
  public final byte type;
  public final int seqid;
 	// ... 
}

// 字段消息头:字段名称-字段类型-字段序号
public class TField {
  public final String name;
  public final byte   type;
  public final short  id;
}

// List 消息头 元素类型-元素个数
public final class TList {
  public final byte elemType;
  public final int  size;
}

// Map 消息头 键类型-值类型-元素个数
public final class TMap {
  public final byte  keyType;
  public final byte  valueType;
  public final int   size;
}

// Set 消息头 元素类型-元素个数
public final class TSet {
  public final byte elemType;
  public final int  size;
}

// Struct 消息头: XXX_args XXX_result 的消息头说明
public final class TStruct {
  public final String name;
}

TMessage 的 equals 方法比较了 name,而 TField 中没有,想想为什么?

因为在 thrift 中,使用参数类型和索引,区分是哪一个参数。而 TMessage 描述的方法调用的元数据。

string sayBye(1: optional string name, 2: optional i32 age)

TField 的 id 属性,表示是参数相对位置的索引,如下方的 1,2。

struct Request {
        1: required i32 age;
        2: required string name;
}

id 为何是 short 类型?引申为 Java 中参数列表支持多少个参数。
https://zhuanlan.zhihu.com/p/44086976
java 中参数列表最大支持 255 个单位长度。

public abstract class TProtocolDecorator extends TProtocol {
    private final TProtocol concreteProtocol;
    public TProtocolDecorator(TProtocol protocol) {
        super(protocol.getTransport());
        concreteProtocol = protocol;
    }
  	// ...
}

TProtocolDecorator采用装饰者模式,将调用委托给内部的 concreteProtocol。

public class TMultiplexedProtocol extends TProtocolDecorator {
    public static final String SEPARATOR = ":";
    private final String SERVICE_NAME;

    public TMultiplexedProtocol(TProtocol protocol, String serviceName) {
        super(protocol);
        SERVICE_NAME = serviceName;
    }

    @Override
    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);
        }
    }
}

使用

TSocket transport = new TSocket("localhost", 9090);
transport.open();
TBinaryProtocol protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
Calculator.Client service = new Calculator.Client(mp);
TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
WeatherReport.Client service2 = new WeatherReport.Client(mp2);
System.out.println(service.add(2,2));
System.out.println(service2.getTemperature());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章