@@ -67,7 +67,7 @@ func (e *ErrClient) Unwrap() error {
6767type clientResponse struct {
6868 Jsonrpc string `json:"jsonrpc"`
6969 Result json.RawMessage `json:"result"`
70- ID int64 `json:"id"`
70+ ID interface {} `json:"id"`
7171 Error * respError `json:"error,omitempty"`
7272}
7373
@@ -167,12 +167,15 @@ func httpClient(ctx context.Context, addr string, namespace string, outs []inter
167167 defer httpResp .Body .Close ()
168168
169169 var resp clientResponse
170-
171170 if err := json .NewDecoder (httpResp .Body ).Decode (& resp ); err != nil {
172171 return clientResponse {}, xerrors .Errorf ("http status %s unmarshaling response: %w" , httpResp .Status , err )
173172 }
174173
175- if resp .ID != * cr .req .ID {
174+ if resp .ID , err = normalizeID (resp .ID ); err != nil {
175+ return clientResponse {}, xerrors .Errorf ("failed to response ID: %w" , err )
176+ }
177+
178+ if resp .ID != cr .req .ID {
176179 return clientResponse {}, xerrors .New ("request and response id didn't match" )
177180 }
178181
@@ -246,7 +249,7 @@ func websocketClient(ctx context.Context, addr string, namespace string, outs []
246249 req : request {
247250 Jsonrpc : "2.0" ,
248251 Method : wsCancel ,
249- Params : []param {{v : reflect .ValueOf (* cr .req .ID )}},
252+ Params : []param {{v : reflect .ValueOf (cr .req .ID )}},
250253 },
251254 }
252255 select {
@@ -468,7 +471,7 @@ func (fn *rpcFunc) processError(err error) []reflect.Value {
468471}
469472
470473func (fn * rpcFunc ) handleRpcCall (args []reflect.Value ) (results []reflect.Value ) {
471- id : = atomic .AddInt64 (& fn .client .idCtr , 1 )
474+ var id interface {} = atomic .AddInt64 (& fn .client .idCtr , 1 )
472475 params := make ([]param , len (args )- fn .hasCtx )
473476 for i , arg := range args [fn .hasCtx :] {
474477 enc , found := fn .client .paramEncoders [arg .Type ()]
@@ -503,9 +506,19 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
503506 retVal , chCtor = fn .client .makeOutChan (ctx , fn .ftyp , fn .valOut )
504507 }
505508
509+ // Prepare the ID to send on the wire.
510+ // We track int64 ids as float64 in the inflight map (because that's what
511+ // they'll be decoded to). encoding/json outputs numbers with their minimal
512+ // encoding, avoding the decimal point when possible, i.e. 3 will never get
513+ // converted to 3.0.
514+ id , err := normalizeID (id )
515+ if err != nil {
516+ return fn .processError (fmt .Errorf ("failed to normalize id" )) // should probably panic
517+ }
518+
506519 req := request {
507520 Jsonrpc : "2.0" ,
508- ID : & id ,
521+ ID : id ,
509522 Method : fn .client .namespace + "." + fn .name ,
510523 Params : params ,
511524 }
@@ -526,7 +539,6 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
526539 }
527540
528541 var resp clientResponse
529- var err error
530542 // keep retrying if got a forced closed websocket conn and calling method
531543 // has retry annotation
532544 for attempt := 0 ; true ; attempt ++ {
@@ -535,7 +547,7 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
535547 return fn .processError (fmt .Errorf ("sendRequest failed: %w" , err ))
536548 }
537549
538- if resp .ID != * req .ID {
550+ if resp .ID != req .ID {
539551 return fn .processError (xerrors .New ("request and response id didn't match" ))
540552 }
541553
0 commit comments