github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/protocol/message/analysis/analysis.go (about) 1 package analysis 2 3 import ( 4 "encoding/json" 5 container2 "github.com/nyan233/littlerpc/core/container" 6 message2 "github.com/nyan233/littlerpc/core/protocol/message" 7 "github.com/nyan233/littlerpc/core/protocol/message/mux" 8 "github.com/nyan233/littlerpc/core/utils/convert" 9 "unsafe" 10 ) 11 12 type messageCopyDefined struct { 13 Scope [2]uint8 14 MsgId uint64 15 PayloadLength uint32 16 ServiceName string 17 MetaData *container2.SliceMap[string, string] 18 PayloadLayout container2.Slice[uint32] 19 Payloads container2.Slice[byte] 20 } 21 22 type Graph struct { 23 First string 24 MsgType string 25 Codec string 26 Encoder string 27 MsgId uint64 28 DataLength uint32 29 ServiceName string 30 MetaData map[string]string 31 PayloadLayout []uint32 32 Payloads []uint8 33 } 34 35 func (g *Graph) String() string { 36 bytes, err := json.Marshal(g) 37 if err != nil { 38 panic(err) 39 } 40 return convert.BytesToString(bytes) 41 } 42 43 type MuxGraph struct { 44 MuxType string 45 StreamId uint32 46 MsgId uint64 47 PayloadLength uint16 48 *Graph 49 } 50 51 func (g *MuxGraph) String() string { 52 bytes, err := json.Marshal(g) 53 if err != nil { 54 panic(err) 55 } 56 return convert.BytesToString(bytes) 57 } 58 59 func NoMux(data []byte) *Graph { 60 g := &Graph{ 61 MetaData: make(map[string]string), 62 } 63 rawMsg := message2.New() 64 msg := (*messageCopyDefined)(unsafe.Pointer(rawMsg)) 65 _ = message2.Unmarshal(data, rawMsg) 66 switch msg.Scope[0] { 67 case message2.MagicNumber: 68 g.First = "no_mux" 69 case mux.Enabled: 70 g.First = "mux" 71 default: 72 g.First = "unknown" 73 } 74 switch rawMsg.GetMsgType() { 75 case message2.Call: 76 g.MsgType = "call" 77 case message2.Return: 78 g.MsgType = "return" 79 case message2.Ping: 80 g.MsgType = "ping" 81 case message2.Pong: 82 g.MsgType = "pong" 83 case message2.ContextCancel: 84 g.MsgType = "context_cancel" 85 default: 86 g.MsgType = "unknown" 87 } 88 if codecScheme := rawMsg.MetaData.Load(message2.CodecScheme); codecScheme != "" { 89 g.Codec = codecScheme 90 } else { 91 g.Codec = message2.DefaultCodec 92 } 93 if encoderScheme := rawMsg.MetaData.Load(message2.CodecScheme); encoderScheme != "" { 94 g.Encoder = encoderScheme 95 } else { 96 g.Encoder = message2.DefaultPacker 97 } 98 g.MsgId = msg.MsgId 99 g.DataLength = msg.PayloadLength 100 g.ServiceName = msg.ServiceName 101 if msg.MetaData != nil { 102 msg.MetaData.Range(func(k, v string) bool { 103 g.MetaData[k] = v 104 return true 105 }) 106 } 107 if msg.PayloadLayout != nil { 108 for _, v := range msg.PayloadLayout { 109 g.PayloadLayout = append(g.PayloadLayout, v) 110 } 111 } 112 if msg.Payloads != nil { 113 for _, v := range msg.Payloads { 114 g.Payloads = append(g.Payloads, v) 115 } 116 } 117 return g 118 } 119 120 func Mux(data []byte) *MuxGraph { 121 var muxBlock mux.Block 122 _ = mux.Unmarshal(data, &muxBlock) 123 g := &MuxGraph{} 124 switch muxBlock.Flags { 125 case mux.Enabled: 126 g.MuxType = "mux_enabled" 127 default: 128 g.MuxType = "unknown" 129 } 130 g.StreamId = muxBlock.StreamId 131 g.MsgId = muxBlock.MsgId 132 g.PayloadLength = muxBlock.PayloadLength 133 if muxBlock.Payloads == nil { 134 return g 135 } 136 g.Graph = NoMux(muxBlock.Payloads) 137 return g 138 }