|
|
@ -78,10 +78,10 @@ type jsonNotification struct { |
|
|
|
type jsonCodec struct { |
|
|
|
type jsonCodec struct { |
|
|
|
closer sync.Once // close closed channel once
|
|
|
|
closer sync.Once // close closed channel once
|
|
|
|
closed chan interface{} // closed on Close
|
|
|
|
closed chan interface{} // closed on Close
|
|
|
|
decMu sync.Mutex // guards d
|
|
|
|
decMu sync.Mutex // guards the decoder
|
|
|
|
d *json.Decoder // decodes incoming requests
|
|
|
|
decode func(v interface{}) error // decoder to allow multiple transports
|
|
|
|
encMu sync.Mutex // guards e
|
|
|
|
encMu sync.Mutex // guards the encoder
|
|
|
|
e *json.Encoder // encodes responses
|
|
|
|
encode func(v interface{}) error // encoder to allow multiple transports
|
|
|
|
rw io.ReadWriteCloser // connection
|
|
|
|
rw io.ReadWriteCloser // connection
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -96,11 +96,29 @@ func (err *jsonError) ErrorCode() int { |
|
|
|
return err.Code |
|
|
|
return err.Code |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// NewJSONCodec creates a new RPC server codec with support for JSON-RPC 2.0
|
|
|
|
// NewCodec creates a new RPC server codec with support for JSON-RPC 2.0 based
|
|
|
|
|
|
|
|
// on explicitly given encoding and decoding methods.
|
|
|
|
|
|
|
|
func NewCodec(rwc io.ReadWriteCloser, encode, decode func(v interface{}) error) ServerCodec { |
|
|
|
|
|
|
|
return &jsonCodec{ |
|
|
|
|
|
|
|
closed: make(chan interface{}), |
|
|
|
|
|
|
|
encode: encode, |
|
|
|
|
|
|
|
decode: decode, |
|
|
|
|
|
|
|
rw: rwc, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NewJSONCodec creates a new RPC server codec with support for JSON-RPC 2.0.
|
|
|
|
func NewJSONCodec(rwc io.ReadWriteCloser) ServerCodec { |
|
|
|
func NewJSONCodec(rwc io.ReadWriteCloser) ServerCodec { |
|
|
|
d := json.NewDecoder(rwc) |
|
|
|
enc := json.NewEncoder(rwc) |
|
|
|
d.UseNumber() |
|
|
|
dec := json.NewDecoder(rwc) |
|
|
|
return &jsonCodec{closed: make(chan interface{}), d: d, e: json.NewEncoder(rwc), rw: rwc} |
|
|
|
dec.UseNumber() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return &jsonCodec{ |
|
|
|
|
|
|
|
closed: make(chan interface{}), |
|
|
|
|
|
|
|
encode: enc.Encode, |
|
|
|
|
|
|
|
decode: dec.Decode, |
|
|
|
|
|
|
|
rw: rwc, |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// isBatch returns true when the first non-whitespace characters is '['
|
|
|
|
// isBatch returns true when the first non-whitespace characters is '['
|
|
|
@ -123,14 +141,12 @@ func (c *jsonCodec) ReadRequestHeaders() ([]rpcRequest, bool, Error) { |
|
|
|
defer c.decMu.Unlock() |
|
|
|
defer c.decMu.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
var incomingMsg json.RawMessage |
|
|
|
var incomingMsg json.RawMessage |
|
|
|
if err := c.d.Decode(&incomingMsg); err != nil { |
|
|
|
if err := c.decode(&incomingMsg); err != nil { |
|
|
|
return nil, false, &invalidRequestError{err.Error()} |
|
|
|
return nil, false, &invalidRequestError{err.Error()} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if isBatch(incomingMsg) { |
|
|
|
if isBatch(incomingMsg) { |
|
|
|
return parseBatchRequest(incomingMsg) |
|
|
|
return parseBatchRequest(incomingMsg) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return parseRequest(incomingMsg) |
|
|
|
return parseRequest(incomingMsg) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -338,7 +354,7 @@ func (c *jsonCodec) Write(res interface{}) error { |
|
|
|
c.encMu.Lock() |
|
|
|
c.encMu.Lock() |
|
|
|
defer c.encMu.Unlock() |
|
|
|
defer c.encMu.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
return c.e.Encode(res) |
|
|
|
return c.encode(res) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Close the underlying connection
|
|
|
|
// Close the underlying connection
|
|
|
|