1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package jsonrpc implements a JSON-RPC 1.0 ClientCodec and ServerCodec
6 // for the rpc package.
7 // For JSON-RPC 2.0 support, see https://godoc.org/?q=json-rpc+2.0
19 type clientCodec
struct {
20 dec
*json
.Decoder
// for reading JSON values
21 enc
*json
.Encoder
// for writing JSON values
24 // temporary work space
28 // JSON-RPC responses include the request id but not the request method.
29 // Package rpc expects both.
30 // We save the request method in pending when sending a request
31 // and then look it up by request ID when filling out the rpc Response.
32 mutex sync
.Mutex
// protects pending
33 pending
map[uint64]string // map request id to method name
36 // NewClientCodec returns a new rpc.ClientCodec using JSON-RPC on conn.
37 func NewClientCodec(conn io
.ReadWriteCloser
) rpc
.ClientCodec
{
39 dec
: json
.NewDecoder(conn
),
40 enc
: json
.NewEncoder(conn
),
42 pending
: make(map[uint64]string),
46 type clientRequest
struct {
47 Method
string `json:"method"`
48 Params
[1]interface{} `json:"params"`
52 func (c
*clientCodec
) WriteRequest(r
*rpc
.Request
, param
interface{}) error
{
54 c
.pending
[r
.Seq
] = r
.ServiceMethod
56 c
.req
.Method
= r
.ServiceMethod
57 c
.req
.Params
[0] = param
59 return c
.enc
.Encode(&c
.req
)
62 type clientResponse
struct {
64 Result
*json
.RawMessage
`json:"result"`
65 Error
interface{} `json:"error"`
68 func (r
*clientResponse
) reset() {
74 func (c
*clientCodec
) ReadResponseHeader(r
*rpc
.Response
) error
{
76 if err
:= c
.dec
.Decode(&c
.resp
); err
!= nil {
81 r
.ServiceMethod
= c
.pending
[c
.resp
.Id
]
82 delete(c
.pending
, c
.resp
.Id
)
87 if c
.resp
.Error
!= nil || c
.resp
.Result
== nil {
88 x
, ok
:= c
.resp
.Error
.(string)
90 return fmt
.Errorf("invalid error %v", c
.resp
.Error
)
93 x
= "unspecified error"
100 func (c
*clientCodec
) ReadResponseBody(x
interface{}) error
{
104 return json
.Unmarshal(*c
.resp
.Result
, x
)
107 func (c
*clientCodec
) Close() error
{
111 // NewClient returns a new rpc.Client to handle requests to the
112 // set of services at the other end of the connection.
113 func NewClient(conn io
.ReadWriteCloser
) *rpc
.Client
{
114 return rpc
.NewClientWithCodec(NewClientCodec(conn
))
117 // Dial connects to a JSON-RPC server at the specified network address.
118 func Dial(network
, address
string) (*rpc
.Client
, error
) {
119 conn
, err
:= net
.Dial(network
, address
)
123 return NewClient(conn
), err