The Thrift Protocol implementation currently has a binary protocol (TBINARYPROTOCOL), a compact binary protocol (TCOMPACTPROTOCOL), and a JSON protocol (TJSONPROTOCOL).
The previous two texts analyze the Tbinaryprotocol and TCOMPACTPROTOCOL protocols from the Coding and Protocol principles, and analyze the Tjsonprotocol protocol below.
The TJSONPROTOCOL protocol is relatively simple, it is transmitted in text mode in the network, and it is easy to grasp the packet analysis and understanding.
1. Data type representation and shorthand
Data Type
Data type |
JSON Protocol node shorthand |
C + + Presentation method |
Go Presentation mode |
How Java is represented |
How LUA is represented |
Boolean |
Tf |
bool |
bool |
Boolean |
True/false |
Bytes/8 bits |
i8 |
Int8_t,char |
int8 |
Byte |
|
16-bit integer |
I16 |
int16_t |
Int16 |
Short |
|
32-bit integer |
I32 |
int32_t |
Int32 |
Int |
|
64-bit integer |
I64 |
int64_t |
Int64 |
Long |
|
Double-precision Decimals |
Dbl |
Double |
Float64 |
Double |
|
String |
Str |
String |
String |
String |
|
Structural body |
Rec |
struct |
struct |
Class |
Table |
List |
Lst |
Std:list<value> |
[]type |
List<valuetype> |
Table[value] = bool |
Collection |
Set |
Std:set<value> |
Map[valuetype]bool |
Set<valuetype> |
Table[value] = bool |
Dictionary/Map |
Map |
Std:map<key, value> |
Map[keytype]valuetype |
Map<keytype,valuetype> |
Table[key] = value |
2. How each data type is represented
JSON representation format for bool,i8,i16,i32,i64,double,string:
"Number": { "type": "Value"},
struct JSON representation format:
"Number": { "rec": {"member number": { "member type": "Member Value" }, ... }
JSON representation format for map:
"Number": { "map": ["Key Type", "value type", number of elements, { "key 1": "Value 1", "Key n": "Value n" } ]},
JSON representation of Set and list:
"Number": { "set/lst": ["Value type", number of elements, "Ele1", "Ele2", "Elen" ]},
3. Write the thrift IDL file and generate the Golang code
Thrift--gen Go Rpc.thrift
Namespace go demo.rpcnamespace cpp demo.rpcnamespace java demo.rpcstruct argstruct { 1:byte argbyte, 2:string Argstring 3:i16 argI16, 4:i32 argI32, 5:i64 argI64, 6:double argdouble, 7:bool argbool,}service rpcservice { list<string> funcall ( 1:argstruct argstruct, 2:byte Argbyte, 3:i16 argI16, 4:i32 argI32, 5:i64 argI64, 6:double argdouble, 7:string argstring, 8:map<string, string> parammapstrstr, 9:map<i32, string> paramMapI32Str, 10:set<string> paramsetstr, 11:set<i64> paramSetI64, 12:list<string> Paramliststr, 13:bool Argbool, ),}
Writing client-side test code
Package main import ("Demo/rpc" "FMT" "Git.apache.org/thrift.git/lib/go/thrift" "NET" "OS" "Time") func Main () {startTime: = Currenttimemillis () transportfactory: = Thrift. Newttransportfactory () Protocolfactory: = Thrift. Newtjsonprotocolfactory () transport, err: = Thrift. Newtsocket (NET. Joinhostport ("10.10.36.143", "8090")) if err! = Nil {fmt. Fprintln (OS. Stderr, "Error resolving Address:", err) OS. Exit (1)} Usetransport: = Transportfactory.gettransport (transport) Client: = RPC. Newrpcserviceclientfactory (Usetransport, protocolfactory) If err: = transport. Open (); Err! = Nil {fmt. Fprintln (OS. Stderr, "Error opening socket to 127.0.0.1:19090", "", err) OS. Exit (1)} defer transport. Close () for I: = 0; i < 1000; i++ {argstruct: = &rpc. argstruct{} argstruct.argbyte = argstruct.argstring = "str value" argstruct.argi16 = Si arg STRUCT.ARGI32 = argstruct.ArgI64 = argstruct.argdouble = 11.22 Argstruct.argbool = True Parammap: = Make (map[string]string) parammap["name"] = "namess" parammap["pass"] = "Vpass" PARAMMAPI32STR: = Make (map[int32]string) PARAMMAPI32STR[10] = "Val10" parammapi32str[20] = "VAL20" PARAMSETSTR: = Make (Map[string]bool) para msetstr["Ele1"] = True paramsetstr["Ele2"] = True paramsetstr["Ele3"] = true paramSetI64: = Make (map[ Int64]bool) paramseti64[11] = True paramseti64[22] = True paramseti64[33] = True Paramliststr : = []string{"L1.", "L2."} R1, E1: = client. Funcall (argstruct, he, Si, si, 11.22, "login", Parammap,parammapi32str, Paramsetstr, paramSetI64 , Paramliststr, False) Fmt. Println (i, "call->", R1, E1) break} EndTime: = Currenttimemillis () fmt. PRINTLN ("program exit. Time-> ", EndTime, StartTime, (Endtime-starttime))}//Convert to milliseconds func CUrrenttimemillis () Int64 {return time. Now (). Unixnano ()/1000000}
Use the JSON protocol with the Newtjsonprotocolfactory method.
Writing Service segment Test code
Package main import ("Demo/rpc" "FMT" "Git.apache.org/thrift.git/lib/go/thrift" "OS") const (NETWORKADDR = ": 8090") type Rpcserviceimpl struct {} func (this *rpcserviceimpl) Funcall (argstruct *rpc. Argstruct, Argbyte int8, ArgI16 int16, argI32 int32, argI64 Int64, argdouble float64, argstring string, parammaps Trstr map[string]string, Parammapi32str map[int32]string, Paramsetstr map[string]bool, paramSetI64 Map[int64]bool, p Aramliststr []string, Argbool bool) (R []string, err Error) {FMT. Println ("-->funcall:", argstruct) R = Append (R, "Return 1 by Funcall.") R = Append (R, "Return 2 by Funcall.") return} func Main () {transportfactory: = thrift. Newttransportfactory () Protocolfactory: = Thrift. Newtjsonprotocolfactory () Servertransport, err: = Thrift. Newtserversocket (NETWORKADDR) if err! = Nil {fmt. Println ("error!", err) OS. Exit (1)} Handler: = &rpcserviceimpl{} Processor: = RPC. Newrpcserviceprocessor (Handler) Server: = Thrift. NewTSimpleServer4 (processor, servertransport,transportfactory, protocolfactory) fmt. PRINTLN ("Thrift Server In", NETWORKADDR) server. Serve ()}
Use the JSON protocol with the Newtjsonprotocolfactory method.
Pre-test Grab packet analysis
Request message:
[1, "Funcall", 1, 1, {"1": {"rec": {"1": {"i8": 53 }, "2": {"str": "str Value"}, "3": { "I16": Si}, "4": {"i32": 12}, "5": {"i64": "6": {"dbl": 11.22 }, "7": {"tf": 1}}, "2": { "I8": "3": {"i16": Si}, "4": {"i32": 12}, "5": {"i64": "6": {"dbl": 11.22}, "7": {"str": "Login" }, "8": {"map": ["str", "str", 2, { "NamE ":" Namess "," Pass ":" Vpass "}]}," 9 ": {" map ": [ "I32", "str", 2, {"Ten": "Val10", "": "Val20"}]}, "ten": {"set": ["str", 3, "Ele1", "Ele2", "Ele3"]}, "11": {"Set": ["i64", 3, 11, 22, 33 ]}, "a": {"LST": ["str", 2, "L1.", "L2." ]}, "all": {"TF": 0}]
Request Message Analysis:
A message is enclosed in brackets [] .
The 1th element 1 represents the protocol version, and the current Tjsonprotocol protocol version is 1.
The 2nd element, Funcall, represents the name of a message.
The 3rd element 1 represents a message request, (Message request: 1, message response: 2, message exception: 3,oneway message: 4).
The 4th element, 1, represents a message serial number.
The parameters of a message are enclosed in curly braces {}.
The node key name for the message parameter is the field number defined in the thrift file, and the node value consists of a value type and a value.
Such as:
"1": { "i8": 53},
1 represents the field number, i8 indicates that the value type is a 8-bit integer or a byte, and 53 represents a value.
The other is the same meaning, no longer repeat.
Response message:
[ 1, "Funcall", 2, 1, { "0": {" lst": [ "str", 2, "return 1 by Funcall.", "Return 2 by Funcall." } }]
Response Message Analysis:
A message is enclosed in brackets [].
The 1th element 1 represents the protocol version, and the current Tjsonprotocol protocol version is 1.
The 2nd element, Funcall, represents the name of a message.
The 3rd element 2 represents a message response, (Message request: 1, message response: 2, message exception: 3,oneway message: 4).
The 4th element, 1, represents a message serial number.
The next field is the returned parameter.
Done.
Analysis of Tjsonprotocol protocol for Thrift