1
0
mirror of https://github.com/go-micro/go-micro.git synced 2024-12-18 08:26:38 +02:00
go-micro/codec/jsonrpc/client.go

100 lines
1.8 KiB
Go
Raw Normal View History

2015-11-28 20:54:38 +02:00
package jsonrpc
2015-11-28 20:40:32 +02:00
import (
"encoding/json"
"fmt"
"io"
"sync"
2021-10-12 13:55:53 +02:00
"go-micro.dev/v4/codec"
2015-11-28 20:40:32 +02:00
)
type clientCodec struct {
// temporary work space
req clientRequest
resp clientResponse
2023-04-26 02:16:34 +02:00
c io.Closer
dec *json.Decoder // for reading JSON values
enc *json.Encoder // for writing JSON values
2019-01-08 17:38:25 +02:00
pending map[interface{}]string
2023-04-26 02:16:34 +02:00
sync.Mutex
2015-11-28 20:40:32 +02:00
}
type clientRequest struct {
Params [1]interface{} `json:"params"`
2019-01-08 17:38:25 +02:00
ID interface{} `json:"id"`
2023-04-26 02:16:34 +02:00
Method string `json:"method"`
2015-11-28 20:40:32 +02:00
}
type clientResponse struct {
2019-01-08 17:38:25 +02:00
ID interface{} `json:"id"`
2015-11-28 20:40:32 +02:00
Result *json.RawMessage `json:"result"`
Error interface{} `json:"error"`
}
func newClientCodec(conn io.ReadWriteCloser) *clientCodec {
return &clientCodec{
dec: json.NewDecoder(conn),
enc: json.NewEncoder(conn),
c: conn,
2019-01-08 17:38:25 +02:00
pending: make(map[interface{}]string),
2015-11-28 20:40:32 +02:00
}
}
func (c *clientCodec) Write(m *codec.Message, b interface{}) error {
c.Lock()
2019-01-18 12:12:57 +02:00
c.pending[m.Id] = m.Method
2015-11-28 20:40:32 +02:00
c.Unlock()
2019-01-18 12:12:57 +02:00
c.req.Method = m.Method
2015-11-28 20:40:32 +02:00
c.req.Params[0] = b
c.req.ID = m.Id
return c.enc.Encode(&c.req)
}
func (r *clientResponse) reset() {
r.ID = 0
r.Result = nil
r.Error = nil
}
func (c *clientCodec) ReadHeader(m *codec.Message) error {
c.resp.reset()
if err := c.dec.Decode(&c.resp); err != nil {
return err
}
c.Lock()
2019-01-18 12:12:57 +02:00
m.Method = c.pending[c.resp.ID]
2015-11-28 20:40:32 +02:00
delete(c.pending, c.resp.ID)
c.Unlock()
m.Error = ""
2019-01-08 17:38:25 +02:00
m.Id = fmt.Sprintf("%v", c.resp.ID)
2015-11-28 20:40:32 +02:00
if c.resp.Error != nil {
x, ok := c.resp.Error.(string)
if !ok {
return fmt.Errorf("invalid error %v", c.resp.Error)
}
if x == "" {
x = "unspecified error"
}
m.Error = x
}
return nil
}
func (c *clientCodec) ReadBody(x interface{}) error {
2016-06-30 17:45:30 +02:00
if x == nil || c.resp.Result == nil {
2015-11-28 20:40:32 +02:00
return nil
}
return json.Unmarshal(*c.resp.Result, x)
}
func (c *clientCodec) Close() error {
return c.c.Close()
}