Four serialization mechanism
4.1 basic knowledge
- Thrift supports serialization and deserialization of binary, compressed format, and json format data. Developers can choose the specific form of the protocol more flexibly. The protocol is freely extensible. The new version of the protocol is fully compatible with the old version!
- Previously, we introduced some basic knowledge of protocol. Let's take a detailed look at its usage
4.2 TProtocol
- This is a protocol interface. We can see how many implementation classes it has
- TBinaryProtocol: it is the default protocol of Thrift. It uses binary coding format for data transmission and basically sends the original data directly
- TCompactProtocol: compressed and dense data transmission protocol, zigzag coding format based on variable length quantity
- TJSONProtocol: use JSON (JavaScript Object Notation) data encoding protocol for data transmission
- TDebugProtocol: it is often used by coders to test and present it in the form of text for easy reading
Basic method
/** * Writing methods. Writing method */ 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; /** * Reading methods. Reading method */ 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;
4.3 TCompactProtocol
- Tcompactprotocol 2 is a Java implementation of the compact protocol specified in THRIFT-110. The basic way to reduce structure overhead is to a) use variable length integers everywhere, and b) use unused bits as much as possible.
- Your savings will obviously vary according to the specific composition of the structure, but in general, the more fields, nested structures, short strings and collections, and low value i32 and i64 fields you have, the more benefits you will see.
- All types:
/** * All of the on-wire type codes. */ private static class Types { public static final byte BOOLEAN_TRUE = 0x01; public static final byte BOOLEAN_FALSE = 0x02; public static final byte BYTE = 0x03; public static final byte I16 = 0x04; public static final byte I32 = 0x05; public static final byte I64 = 0x06; public static final byte DOUBLE = 0x07; public static final byte BINARY = 0x08; public static final byte LIST = 0x09; public static final byte SET = 0x0A; public static final byte MAP = 0x0B; public static final byte STRUCT = 0x0C; }
Source code analysis
package com.example.thrift.client; import com.example.thrift.thrift.person; import com.example.thrift.thrift.personservice; import org.apache.thrift.TException; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.layered.TFramedTransport; /** * @Author shu * @Description Customer service end **/ public class ThriftClient { public static void main(String[] args) { TTransport transport =null; try { // connect transport = new TFramedTransport(new TSocket("127.0.0.1",8803),600); // agreement TProtocol protocol = new TCompactProtocol(transport); // Call method personservice.Client client = new personservice.Client(protocol); // open a connection transport.open(); // Call method person result = client.getPersonInfoByUserNmae("Ha ha ha ha"); System.out.println("Result =: " + result); } catch (TException e) { e.printStackTrace(); } finally { if (null != transport) { transport.close(); } } } }
- Click our custom method getPersonInfoByUserNmae to see the service generated by thrift
public person getPersonInfoByUserNmae(String username) throws personexception, org.apache.thrift.TException { send_getPersonInfoByUserNmae(username); return recv_getPersonInfoByUserNmae(); } public void send_getPersonInfoByUserNmae(String username) throws org.apache.thrift.TException { getPersonInfoByUserNmae_args args = new getPersonInfoByUserNmae_args(); args.setUsername(username); // Key method: sending data sendBase("getPersonInfoByUserNmae", args); }
- After entering the sendBase method, you can see that it actually calls the implementation method of TCompactProtocol
protected void sendBase(String methodName, TBase<?,?> args) throws TException { sendBase(methodName, args, TMessageType.CALL); } // Write the data into the specific implementation protocol private void sendBase(String methodName, TBase<?,?> args, byte type) throws TException { // Write start, protocol basic information oprot_.writeMessageBegin(new TMessage(methodName, type, ++seqid_)); // write in args.write(oprot_); // Write end oprot_.writeMessageEnd(); // refresh data oprot_.getTransport().flush(); }
/**Write the message header to the line. The compact protocol message contains the protocol version * Write a message header to the wire. Compact Protocol messages contain the * protocol version so we can migrate forwards in the future if need be. */ @Override public void writeMessageBegin(TMessage message) throws TException { // Agreement No writeByteDirect(PROTOCOL_ID); // edition writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); // serial number writeVarint32(message.seqid); // Message name writeString(message.name); }
- General basic interface of generated Thrift object: TSerializable
public interface TSerializable { /** * Reads the TObject from the given input protocol. *Read object from protocol * @param iprot Input protocol */ public void read(TProtocol iprot) throws TException; /** * Writes the objects out to the protocol *Write object to protocol * @param oprot Output protocol */ public void write(TProtocol oprot) throws TException; }
- Obviously, this calls the method generated by thrift
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { scheme(oprot).write(oprot, this); }
- Call the TCompactProtocol method to start writing
public void write(org.apache.thrift.protocol.TProtocol oprot, getPersonInfoByUserNmae_args struct) throws org.apache.thrift.TException { struct.validate(); oprot.writeStructBegin(STRUCT_DESC); if (struct.username != null) { oprot.writeFieldBegin(USERNAME_FIELD_DESC); oprot.writeString(struct.username); oprot.writeFieldEnd(); } oprot.writeFieldStop(); oprot.writeStructEnd(); } }
- Different from the write method, the read method calls the read implementation class of the TSerializabl interface. In fact, it also calls the methods in the service generated by thrift.
public interface IScheme<T extends TBase> { public void read(org.apache.thrift.protocol.TProtocol iproto, T struct) throws org.apache.thrift.TException; public void write(org.apache.thrift.protocol.TProtocol oproto, T struct) throws org.apache.thrift.TException; }