github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/util/codec/jsonrpc/client.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/codec/jsonrpc/client.go 14 15 package jsonrpc 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io" 21 "sync" 22 23 "github.com/tickoalcantara12/micro/v3/util/codec" 24 ) 25 26 type clientCodec struct { 27 dec *json.Decoder // for reading JSON values 28 enc *json.Encoder // for writing JSON values 29 c io.Closer 30 31 // temporary work space 32 req clientRequest 33 resp clientResponse 34 35 sync.Mutex 36 pending map[interface{}]string 37 } 38 39 type clientRequest struct { 40 Method string `json:"method"` 41 Params [1]interface{} `json:"params"` 42 ID interface{} `json:"id"` 43 } 44 45 type clientResponse struct { 46 ID interface{} `json:"id"` 47 Result *json.RawMessage `json:"result"` 48 Error interface{} `json:"error"` 49 } 50 51 func newClientCodec(conn io.ReadWriteCloser) *clientCodec { 52 return &clientCodec{ 53 dec: json.NewDecoder(conn), 54 enc: json.NewEncoder(conn), 55 c: conn, 56 pending: make(map[interface{}]string), 57 } 58 } 59 60 func (c *clientCodec) Write(m *codec.Message, b interface{}) error { 61 c.Lock() 62 c.pending[m.Id] = m.Method 63 c.Unlock() 64 c.req.Method = m.Method 65 c.req.Params[0] = b 66 c.req.ID = m.Id 67 return c.enc.Encode(&c.req) 68 } 69 70 func (r *clientResponse) reset() { 71 r.ID = 0 72 r.Result = nil 73 r.Error = nil 74 } 75 76 func (c *clientCodec) ReadHeader(m *codec.Message) error { 77 c.resp.reset() 78 if err := c.dec.Decode(&c.resp); err != nil { 79 return err 80 } 81 82 c.Lock() 83 m.Method = c.pending[c.resp.ID] 84 delete(c.pending, c.resp.ID) 85 c.Unlock() 86 87 m.Error = "" 88 m.Id = fmt.Sprintf("%v", c.resp.ID) 89 if c.resp.Error != nil { 90 x, ok := c.resp.Error.(string) 91 if !ok { 92 return fmt.Errorf("invalid error %v", c.resp.Error) 93 } 94 if x == "" { 95 x = "unspecified error" 96 } 97 m.Error = x 98 } 99 return nil 100 } 101 102 func (c *clientCodec) ReadBody(x interface{}) error { 103 if x == nil || c.resp.Result == nil { 104 return nil 105 } 106 return json.Unmarshal(*c.resp.Result, x) 107 } 108 109 func (c *clientCodec) Close() error { 110 return c.c.Close() 111 }