github.com/annwntech/go-micro/v2@v2.9.5/client/grpc/codec.go (about) 1 package grpc 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 b "bytes" 9 10 "github.com/annwntech/go-micro/v2/codec" 11 "github.com/annwntech/go-micro/v2/codec/bytes" 12 "github.com/golang/protobuf/jsonpb" 13 "github.com/golang/protobuf/proto" 14 "github.com/oxtoacart/bpool" 15 "google.golang.org/grpc" 16 "google.golang.org/grpc/encoding" 17 ) 18 19 type jsonCodec struct{} 20 type protoCodec struct{} 21 type bytesCodec struct{} 22 type wrapCodec struct{ encoding.Codec } 23 24 var ( 25 JsonpbMarshaler = &jsonpb.Marshaler{ 26 EnumsAsInts: false, 27 EmitDefaults: true, 28 OrigName: true, 29 } 30 JsonpbUnmarshaler = &jsonpb.Unmarshaler{ 31 AllowUnknownFields: false, 32 } 33 ) 34 var useNumber bool 35 36 // create buffer pool with 16 instances each preallocated with 256 bytes 37 var bufferPool = bpool.NewSizedBufferPool(16, 256) 38 39 var ( 40 defaultGRPCCodecs = map[string]encoding.Codec{ 41 "application/json": jsonCodec{}, 42 "application/proto": protoCodec{}, 43 "application/protobuf": protoCodec{}, 44 "application/octet-stream": protoCodec{}, 45 "application/grpc": protoCodec{}, 46 "application/grpc+json": jsonCodec{}, 47 "application/grpc+proto": protoCodec{}, 48 "application/grpc+bytes": bytesCodec{}, 49 } 50 ) 51 52 // UseNumber fix unmarshal Number(8234567890123456789) to interface(8.234567890123457e+18) 53 func UseNumber() { 54 useNumber = true 55 } 56 57 func (w wrapCodec) String() string { 58 return w.Codec.Name() 59 } 60 61 func (w wrapCodec) Marshal(v interface{}) ([]byte, error) { 62 b, ok := v.(*bytes.Frame) 63 if ok { 64 return b.Data, nil 65 } 66 return w.Codec.Marshal(v) 67 } 68 69 func (w wrapCodec) Unmarshal(data []byte, v interface{}) error { 70 b, ok := v.(*bytes.Frame) 71 if ok { 72 b.Data = data 73 return nil 74 } 75 return w.Codec.Unmarshal(data, v) 76 } 77 78 func (protoCodec) Marshal(v interface{}) ([]byte, error) { 79 switch m := v.(type) { 80 case *bytes.Frame: 81 return m.Data, nil 82 case proto.Message: 83 return proto.Marshal(m) 84 } 85 return nil, fmt.Errorf("failed to marshal: %v is not type of *bytes.Frame or proto.Message", v) 86 } 87 88 func (protoCodec) Unmarshal(data []byte, v interface{}) error { 89 m, ok := v.(proto.Message) 90 if !ok { 91 return fmt.Errorf("failed to unmarshal: %v is not type of proto.Message", v) 92 } 93 return proto.Unmarshal(data, m) 94 } 95 96 func (protoCodec) Name() string { 97 return "proto" 98 } 99 100 func (bytesCodec) Marshal(v interface{}) ([]byte, error) { 101 b, ok := v.(*[]byte) 102 if !ok { 103 return nil, fmt.Errorf("failed to marshal: %v is not type of *[]byte", v) 104 } 105 return *b, nil 106 } 107 108 func (bytesCodec) Unmarshal(data []byte, v interface{}) error { 109 b, ok := v.(*[]byte) 110 if !ok { 111 return fmt.Errorf("failed to unmarshal: %v is not type of *[]byte", v) 112 } 113 *b = data 114 return nil 115 } 116 117 func (bytesCodec) Name() string { 118 return "bytes" 119 } 120 121 func (jsonCodec) Marshal(v interface{}) ([]byte, error) { 122 if b, ok := v.(*bytes.Frame); ok { 123 return b.Data, nil 124 } 125 126 if pb, ok := v.(proto.Message); ok { 127 buf := bufferPool.Get() 128 defer bufferPool.Put(buf) 129 if err := JsonpbMarshaler.Marshal(buf, pb); err != nil { 130 return nil, err 131 } 132 return buf.Bytes(), nil 133 } 134 135 return json.Marshal(v) 136 } 137 138 func (jsonCodec) Unmarshal(data []byte, v interface{}) error { 139 if len(data) == 0 { 140 return nil 141 } 142 if b, ok := v.(*bytes.Frame); ok { 143 b.Data = data 144 return nil 145 } 146 if pb, ok := v.(proto.Message); ok { 147 return JsonpbUnmarshaler.Unmarshal(b.NewReader(data), pb) 148 } 149 150 dec := json.NewDecoder(b.NewReader(data)) 151 if useNumber { 152 dec.UseNumber() 153 } 154 return dec.Decode(v) 155 } 156 157 func (jsonCodec) Name() string { 158 return "json" 159 } 160 161 type grpcCodec struct { 162 // headers 163 id string 164 target string 165 method string 166 endpoint string 167 168 s grpc.ClientStream 169 c encoding.Codec 170 } 171 172 func (g *grpcCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error { 173 md, err := g.s.Header() 174 if err != nil { 175 return err 176 } 177 if m == nil { 178 m = new(codec.Message) 179 } 180 if m.Header == nil { 181 m.Header = make(map[string]string, len(md)) 182 } 183 for k, v := range md { 184 m.Header[k] = strings.Join(v, ",") 185 } 186 m.Id = g.id 187 m.Target = g.target 188 m.Method = g.method 189 m.Endpoint = g.endpoint 190 return nil 191 } 192 193 func (g *grpcCodec) ReadBody(v interface{}) error { 194 if f, ok := v.(*bytes.Frame); ok { 195 return g.s.RecvMsg(f) 196 } 197 return g.s.RecvMsg(v) 198 } 199 200 func (g *grpcCodec) Write(m *codec.Message, v interface{}) error { 201 // if we don't have a body 202 if v != nil { 203 return g.s.SendMsg(v) 204 } 205 // write the body using the framing codec 206 return g.s.SendMsg(&bytes.Frame{Data: m.Body}) 207 } 208 209 func (g *grpcCodec) Close() error { 210 return g.s.CloseSend() 211 } 212 213 func (g *grpcCodec) String() string { 214 return g.c.Name() 215 }