github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/rpc/json.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:42</date> 10 //</624450109135917056> 11 12 13 package rpc 14 15 import ( 16 "bytes" 17 "encoding/json" 18 "fmt" 19 "io" 20 "reflect" 21 "strconv" 22 "strings" 23 "sync" 24 25 "github.com/ethereum/go-ethereum/log" 26 ) 27 28 const ( 29 jsonrpcVersion = "2.0" 30 serviceMethodSeparator = "_" 31 subscribeMethodSuffix = "_subscribe" 32 unsubscribeMethodSuffix = "_unsubscribe" 33 notificationMethodSuffix = "_subscription" 34 ) 35 36 type jsonRequest struct { 37 Method string `json:"method"` 38 Version string `json:"jsonrpc"` 39 Id json.RawMessage `json:"id,omitempty"` 40 Payload json.RawMessage `json:"params,omitempty"` 41 } 42 43 type jsonSuccessResponse struct { 44 Version string `json:"jsonrpc"` 45 Id interface{} `json:"id,omitempty"` 46 Result interface{} `json:"result"` 47 } 48 49 type jsonError struct { 50 Code int `json:"code"` 51 Message string `json:"message"` 52 Data interface{} `json:"data,omitempty"` 53 } 54 55 type jsonErrResponse struct { 56 Version string `json:"jsonrpc"` 57 Id interface{} `json:"id,omitempty"` 58 Error jsonError `json:"error"` 59 } 60 61 type jsonSubscription struct { 62 Subscription string `json:"subscription"` 63 Result interface{} `json:"result,omitempty"` 64 } 65 66 type jsonNotification struct { 67 Version string `json:"jsonrpc"` 68 Method string `json:"method"` 69 Params jsonSubscription `json:"params"` 70 } 71 72 //jsondec读取JSON-RPC消息并将其写入基础连接。它 73 //还支持解析参数和序列化(结果)对象。 74 type jsonCodec struct { 75 closer sync.Once //关闭关闭通道一次 76 closed chan interface{} //关闭关闭 77 decMu sync.Mutex //保护解码器 78 decode func(v interface{}) error //允许多个传输的解码器 79 encMu sync.Mutex //保护编码器 80 encode func(v interface{}) error //允许多个传输的编码器 81 rw io.ReadWriteCloser //连接 82 } 83 84 func (err *jsonError) Error() string { 85 if err.Message == "" { 86 return fmt.Sprintf("json-rpc error %d", err.Code) 87 } 88 return err.Message 89 } 90 91 func (err *jsonError) ErrorCode() int { 92 return err.Code 93 } 94 95 //Newcodec创建了一个新的RPC服务器编解码器,支持基于JSON-RPC2.0的 96 //关于显式给定的编码和解码方法。 97 func NewCodec(rwc io.ReadWriteCloser, encode, decode func(v interface{}) error) ServerCodec { 98 return &jsonCodec{ 99 closed: make(chan interface{}), 100 encode: encode, 101 decode: decode, 102 rw: rwc, 103 } 104 } 105 106 //newjsondec创建了一个新的RPC服务器编解码器,支持json-rpc 2.0。 107 func NewJSONCodec(rwc io.ReadWriteCloser) ServerCodec { 108 enc := json.NewEncoder(rwc) 109 dec := json.NewDecoder(rwc) 110 dec.UseNumber() 111 112 return &jsonCodec{ 113 closed: make(chan interface{}), 114 encode: enc.Encode, 115 decode: dec.Decode, 116 rw: rwc, 117 } 118 } 119 120 //当第一个非空白字符为“[”时,isbatch返回true 121 func isBatch(msg json.RawMessage) bool { 122 for _, c := range msg { 123 //跳过不重要的空白(http://www.ietf.org/rfc/rfc4627.txt) 124 if c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d { 125 continue 126 } 127 return c == '[' 128 } 129 return false 130 } 131 132 //readRequestHeaders将在不分析参数的情况下读取新请求。它将 133 //返回请求集合,指示这些请求是否成批 134 //窗体或传入消息无法读取/分析时出错。 135 func (c *jsonCodec) ReadRequestHeaders() ([]rpcRequest, bool, Error) { 136 c.decMu.Lock() 137 defer c.decMu.Unlock() 138 139 var incomingMsg json.RawMessage 140 if err := c.decode(&incomingMsg); err != nil { 141 return nil, false, &invalidRequestError{err.Error()} 142 } 143 if isBatch(incomingMsg) { 144 return parseBatchRequest(incomingMsg) 145 } 146 return parseRequest(incomingMsg) 147 } 148 149 //当给定的reqid对rpc方法调用无效时,checkreqid返回一个错误。 150 //有效ID是字符串、数字或空值 151 func checkReqId(reqId json.RawMessage) error { 152 if len(reqId) == 0 { 153 return fmt.Errorf("missing request id") 154 } 155 if _, err := strconv.ParseFloat(string(reqId), 64); err == nil { 156 return nil 157 } 158 var str string 159 if err := json.Unmarshal(reqId, &str); err == nil { 160 return nil 161 } 162 return fmt.Errorf("invalid request id") 163 } 164 165 //ParseRequest将解析来自给定rawMessage的单个请求。它会回来 166 //解析的请求,指示请求是批处理还是错误,当 167 //无法分析请求。 168 func parseRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, Error) { 169 var in jsonRequest 170 if err := json.Unmarshal(incomingMsg, &in); err != nil { 171 return nil, false, &invalidMessageError{err.Error()} 172 } 173 174 if err := checkReqId(in.Id); err != nil { 175 return nil, false, &invalidMessageError{err.Error()} 176 } 177 178 //订阅是特殊的,它们将始终使用'subscripbemethod'作为有效负载中的第一个参数 179 if strings.HasSuffix(in.Method, subscribeMethodSuffix) { 180 reqs := []rpcRequest{{id: &in.Id, isPubSub: true}} 181 if len(in.Payload) > 0 { 182 //第一个参数必须是订阅名称 183 var subscribeMethod [1]string 184 if err := json.Unmarshal(in.Payload, &subscribeMethod); err != nil { 185 log.Debug(fmt.Sprintf("Unable to parse subscription method: %v\n", err)) 186 return nil, false, &invalidRequestError{"Unable to parse subscription request"} 187 } 188 189 reqs[0].service, reqs[0].method = strings.TrimSuffix(in.Method, subscribeMethodSuffix), subscribeMethod[0] 190 reqs[0].params = in.Payload 191 return reqs, false, nil 192 } 193 return nil, false, &invalidRequestError{"Unable to parse subscription request"} 194 } 195 196 if strings.HasSuffix(in.Method, unsubscribeMethodSuffix) { 197 return []rpcRequest{{id: &in.Id, isPubSub: true, 198 method: in.Method, params: in.Payload}}, false, nil 199 } 200 201 elems := strings.Split(in.Method, serviceMethodSeparator) 202 if len(elems) != 2 { 203 return nil, false, &methodNotFoundError{in.Method, ""} 204 } 205 206 //常规RPC调用 207 if len(in.Payload) == 0 { 208 return []rpcRequest{{service: elems[0], method: elems[1], id: &in.Id}}, false, nil 209 } 210 211 return []rpcRequest{{service: elems[0], method: elems[1], id: &in.Id, params: in.Payload}}, false, nil 212 } 213 214 //ParseBatchRequest将批处理请求解析为来自给定rawMessage的请求集合,指示 215 //如果请求是批处理或无法读取请求时出错。 216 func parseBatchRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, Error) { 217 var in []jsonRequest 218 if err := json.Unmarshal(incomingMsg, &in); err != nil { 219 return nil, false, &invalidMessageError{err.Error()} 220 } 221 222 requests := make([]rpcRequest, len(in)) 223 for i, r := range in { 224 if err := checkReqId(r.Id); err != nil { 225 return nil, false, &invalidMessageError{err.Error()} 226 } 227 228 id := &in[i].Id 229 230 //订阅是特殊的,它们将始终使用'subscriptionmethod'作为有效负载中的第一个参数 231 if strings.HasSuffix(r.Method, subscribeMethodSuffix) { 232 requests[i] = rpcRequest{id: id, isPubSub: true} 233 if len(r.Payload) > 0 { 234 //第一个参数必须是订阅名称 235 var subscribeMethod [1]string 236 if err := json.Unmarshal(r.Payload, &subscribeMethod); err != nil { 237 log.Debug(fmt.Sprintf("Unable to parse subscription method: %v\n", err)) 238 return nil, false, &invalidRequestError{"Unable to parse subscription request"} 239 } 240 241 requests[i].service, requests[i].method = strings.TrimSuffix(r.Method, subscribeMethodSuffix), subscribeMethod[0] 242 requests[i].params = r.Payload 243 continue 244 } 245 246 return nil, true, &invalidRequestError{"Unable to parse (un)subscribe request arguments"} 247 } 248 249 if strings.HasSuffix(r.Method, unsubscribeMethodSuffix) { 250 requests[i] = rpcRequest{id: id, isPubSub: true, method: r.Method, params: r.Payload} 251 continue 252 } 253 254 if len(r.Payload) == 0 { 255 requests[i] = rpcRequest{id: id, params: nil} 256 } else { 257 requests[i] = rpcRequest{id: id, params: r.Payload} 258 } 259 if elem := strings.Split(r.Method, serviceMethodSeparator); len(elem) == 2 { 260 requests[i].service, requests[i].method = elem[0], elem[1] 261 } else { 262 requests[i].err = &methodNotFoundError{r.Method, ""} 263 } 264 } 265 266 return requests, true, nil 267 } 268 269 //ParseRequestArguments尝试使用给定的 270 //类型。它返回已分析的值,或者在分析失败时返回错误。 271 func (c *jsonCodec) ParseRequestArguments(argTypes []reflect.Type, params interface{}) ([]reflect.Value, Error) { 272 if args, ok := params.(json.RawMessage); !ok { 273 return nil, &invalidParamsError{"Invalid params supplied"} 274 } else { 275 return parsePositionalArguments(args, argTypes) 276 } 277 } 278 279 //ParsePositionalArguments尝试将给定的参数解析为具有 280 //给定类型。它返回已分析的值,或者当参数不能 281 //解析。缺少的可选参数作为reflect.zero值返回。 282 func parsePositionalArguments(rawArgs json.RawMessage, types []reflect.Type) ([]reflect.Value, Error) { 283 //读取args数组的开头。 284 dec := json.NewDecoder(bytes.NewReader(rawArgs)) 285 if tok, _ := dec.Token(); tok != json.Delim('[') { 286 return nil, &invalidParamsError{"non-array args"} 287 } 288 //读取ARG。 289 args := make([]reflect.Value, 0, len(types)) 290 for i := 0; dec.More(); i++ { 291 if i >= len(types) { 292 return nil, &invalidParamsError{fmt.Sprintf("too many arguments, want at most %d", len(types))} 293 } 294 argval := reflect.New(types[i]) 295 if err := dec.Decode(argval.Interface()); err != nil { 296 return nil, &invalidParamsError{fmt.Sprintf("invalid argument %d: %v", i, err)} 297 } 298 if argval.IsNil() && types[i].Kind() != reflect.Ptr { 299 return nil, &invalidParamsError{fmt.Sprintf("missing value for required argument %d", i)} 300 } 301 args = append(args, argval.Elem()) 302 } 303 //读取args数组的结尾。 304 if _, err := dec.Token(); err != nil { 305 return nil, &invalidParamsError{err.Error()} 306 } 307 //将所有缺少的参数设置为零。 308 for i := len(args); i < len(types); i++ { 309 if types[i].Kind() != reflect.Ptr { 310 return nil, &invalidParamsError{fmt.Sprintf("missing value for required argument %d", i)} 311 } 312 args = append(args, reflect.Zero(types[i])) 313 } 314 return args, nil 315 } 316 317 //createResponse将使用给定的ID创建一个JSON-RPC成功响应,并作为结果进行回复。 318 func (c *jsonCodec) CreateResponse(id interface{}, reply interface{}) interface{} { 319 return &jsonSuccessResponse{Version: jsonrpcVersion, Id: id, Result: reply} 320 } 321 322 //CreateErrorResponse将使用给定的ID和错误创建JSON-RPC错误响应。 323 func (c *jsonCodec) CreateErrorResponse(id interface{}, err Error) interface{} { 324 return &jsonErrResponse{Version: jsonrpcVersion, Id: id, Error: jsonError{Code: err.ErrorCode(), Message: err.Error()}} 325 } 326 327 //CreateErrorResponseWithInfo将使用给定的ID和错误创建JSON-RPC错误响应。 328 //信息是可选的,包含有关错误的其他信息。当传递空字符串时,它将被忽略。 329 func (c *jsonCodec) CreateErrorResponseWithInfo(id interface{}, err Error, info interface{}) interface{} { 330 return &jsonErrResponse{Version: jsonrpcVersion, Id: id, 331 Error: jsonError{Code: err.ErrorCode(), Message: err.Error(), Data: info}} 332 } 333 334 //createNotification将创建一个具有给定订阅ID和事件作为参数的JSON-RPC通知。 335 func (c *jsonCodec) CreateNotification(subid, namespace string, event interface{}) interface{} { 336 return &jsonNotification{Version: jsonrpcVersion, Method: namespace + notificationMethodSuffix, 337 Params: jsonSubscription{Subscription: subid, Result: event}} 338 } 339 340 //向客户端写入消息 341 func (c *jsonCodec) Write(res interface{}) error { 342 c.encMu.Lock() 343 defer c.encMu.Unlock() 344 345 return c.encode(res) 346 } 347 348 //关闭基础连接 349 func (c *jsonCodec) Close() { 350 c.closer.Do(func() { 351 close(c.closed) 352 c.rw.Close() 353 }) 354 } 355 356 //CLOSED返回调用CLOSE时将关闭的通道 357 func (c *jsonCodec) Closed() <-chan interface{} { 358 return c.closed 359 } 360