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());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章