Documentation ¶
Overview ¶
Package jsonrpc2 provides a client and server implementation of [JSON-RPC 2.0](http://www.jsonrpc.org/specification).
Index ¶
- Constants
- Variables
- type CallOption
- type Conn
- func (c *Conn) Call(ctx context.Context, method string, params, result interface{}, ...) error
- func (c *Conn) Close() error
- func (c *Conn) DisconnectNotify() <-chan struct{}
- func (c *Conn) DispatchCall(ctx context.Context, method string, params interface{}, opts ...CallOption) (Waiter, error)
- func (c *Conn) Notify(ctx context.Context, method string, params interface{}, opts ...CallOption) error
- func (c *Conn) Reply(ctx context.Context, id ID, result interface{}) error
- func (c *Conn) ReplyWithError(ctx context.Context, id ID, respErr *Error) error
- func (c *Conn) SendResponse(ctx context.Context, resp *Response) error
- type ConnOpt
- type Error
- type Handler
- type HandlerWithErrorConfigurer
- type ID
- type JSONRPC2
- type Logger
- type ObjectCodec
- type ObjectStream
- type PlainObjectCodecdeprecated
- type Request
- type RequestField
- type Response
- type VSCodeObjectCodec
- type VarintObjectCodec
- type Waiter
Examples ¶
Constants ¶
const ( CodeParseError = -32700 CodeInvalidRequest = -32600 CodeMethodNotFound = -32601 CodeInvalidParams = -32602 CodeInternalError = -32603 )
Errors defined in the JSON-RPC spec. See http://www.jsonrpc.org/specification#error_object.
Variables ¶
var ErrClosed = errors.New("jsonrpc2: connection is closed")
ErrClosed indicates that the JSON-RPC connection is closed (or in the process of closing).
Functions ¶
This section is empty.
Types ¶
type CallOption ¶
type CallOption interface {
// contains filtered or unexported methods
}
CallOption is an option that can be provided to (*Conn).Call to configure custom behavior. See Meta.
func ExtraField ¶ added in v0.2.0
func ExtraField(name string, value interface{}) CallOption
ExtraField returns a call option which attaches the given name/value pair to the JSON-RPC 2.0 request. This can be used to add arbitrary extensions to JSON RPC 2.0.
func Meta ¶
func Meta(meta interface{}) CallOption
Meta returns a call option which attaches the given meta object to the JSON-RPC 2.0 request (this is a Sourcegraph extension to JSON RPC 2.0 for carrying metadata).
func PickID ¶
func PickID(id ID) CallOption
PickID returns a call option which sets the ID on a request. Care must be taken to ensure there are no conflicts with any previously picked ID, nor with the default sequence ID.
func StringID ¶
func StringID() CallOption
StringID returns a call option that instructs the request ID to be set as a string.
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is a JSON-RPC client/server connection. The JSON-RPC protocol is symmetric, so a Conn runs on both ends of a client-server connection.
func NewConn ¶
NewConn creates a new JSON-RPC client/server connection using the given ReadWriteCloser (typically a TCP connection or stdio). The JSON-RPC protocol is symmetric, so a Conn runs on both ends of a client-server connection.
NewClient consumes conn, so you should call Close on the returned client not on the given conn.
func (*Conn) Call ¶
func (c *Conn) Call(ctx context.Context, method string, params, result interface{}, opts ...CallOption) error
Call initiates a JSON-RPC call using the specified method and params, and waits for the response. If the response is successful, its result is stored in result (a pointer to a value that can be JSON-unmarshaled into); otherwise, a non-nil error is returned. See DispatchCall for more details.
func (*Conn) Close ¶
Close closes the JSON-RPC connection. The connection may not be used after it has been closed.
func (*Conn) DisconnectNotify ¶
func (c *Conn) DisconnectNotify() <-chan struct{}
DisconnectNotify returns a channel that is closed when the underlying connection is disconnected.
func (*Conn) DispatchCall ¶
func (c *Conn) DispatchCall(ctx context.Context, method string, params interface{}, opts ...CallOption) (Waiter, error)
DispatchCall dispatches a JSON-RPC call using the specified method and params, and returns a call proxy or an error. Call Wait() on the returned proxy to receive the response. Only use this function if you need to do work after dispatching the request, otherwise use Call.
The params member is omitted from the JSON-RPC request if the given params is nil. Use json.RawMessage("null") to send a JSON-RPC request with its params member set to null.
func (*Conn) Notify ¶
func (c *Conn) Notify(ctx context.Context, method string, params interface{}, opts ...CallOption) error
Notify is like Call, but it returns when the notification request is sent (without waiting for a response, because JSON-RPC notifications do not have responses).
The params member is omitted from the JSON-RPC request if the given params is nil. Use json.RawMessage("null") to send a JSON-RPC request with its params member set to null.
Example (NullParams) ¶
Send a JSON-RPC notification with its params member set to null.
package main import ( "context" "encoding/json" "fmt" "net" "os" "github.com/sourcegraph/jsonrpc2" ) func main() { ctx := context.Background() connA, connB := net.Pipe() defer connA.Close() defer connB.Close() rpcConn := jsonrpc2.NewConn(ctx, jsonrpc2.NewPlainObjectStream(connA), nil) // Send the JSON-RPC notification. go func() { // Set params to the JSON null value. params := json.RawMessage("null") if err := rpcConn.Notify(ctx, "foo", params); err != nil { fmt.Fprintln(os.Stderr, "notify:", err) } }() // Read the raw JSON-RPC notification on connB. // // Reading the raw JSON-RPC request is for the purpose of this example only. // Use a jsonrpc2.Handler to read parsed requests. buf := make([]byte, 64) n, err := connB.Read(buf) if err != nil { fmt.Fprintln(os.Stderr, "read:", err) } fmt.Printf("%s\n", buf[:n]) }
Output: {"jsonrpc":"2.0","method":"foo","params":null}
Example (ParamsOmitted) ¶
Send a JSON-RPC notification with its params member omitted.
package main import ( "context" "fmt" "net" "os" "github.com/sourcegraph/jsonrpc2" ) func main() { ctx := context.Background() connA, connB := net.Pipe() defer connA.Close() defer connB.Close() rpcConn := jsonrpc2.NewConn(ctx, jsonrpc2.NewPlainObjectStream(connA), nil) // Send the JSON-RPC notification. go func() { // Set params to nil. if err := rpcConn.Notify(ctx, "foo", nil); err != nil { fmt.Fprintln(os.Stderr, "notify:", err) } }() // Read the raw JSON-RPC notification on connB. // // Reading the raw JSON-RPC request is for the purpose of this example only. // Use a jsonrpc2.Handler to read parsed requests. buf := make([]byte, 64) n, err := connB.Read(buf) if err != nil { fmt.Fprintln(os.Stderr, "read:", err) } fmt.Printf("%s\n", buf[:n]) }
Output: {"jsonrpc":"2.0","method":"foo"}
func (*Conn) ReplyWithError ¶
ReplyWithError sends a response with an error.
type ConnOpt ¶
type ConnOpt func(*Conn)
ConnOpt is the type of function that can be passed to NewConn to customize the Conn before it is created.
func LogMessages ¶
LogMessages causes all messages sent and received on conn to be logged using the provided logger.
func OnRecv ¶
OnRecv causes all requests received on conn to invoke f(req, nil) and all responses to invoke f(req, resp),
type Error ¶
type Error struct { Code int64 `json:"code"` Message string `json:"message"` Data *json.RawMessage `json:"data,omitempty"` }
Error represents a JSON-RPC response error.
type Handler ¶
type Handler interface { // Handle is called to handle a request. No other requests are handled // until it returns. If you do not require strict ordering behavior // of received RPCs, it is suggested to wrap your handler in // AsyncHandler. Handle(context.Context, *Conn, *Request) }
Handler handles JSON-RPC requests and notifications.
func AsyncHandler ¶
AsyncHandler wraps a Handler such that each request is handled in its own goroutine. It is a convenience wrapper.
type HandlerWithErrorConfigurer ¶
type HandlerWithErrorConfigurer struct {
// contains filtered or unexported fields
}
HandlerWithErrorConfigurer is a handler created by HandlerWithError.
func HandlerWithError ¶
func HandlerWithError(handleFunc func(context.Context, *Conn, *Request) (result interface{}, err error)) *HandlerWithErrorConfigurer
HandlerWithError implements Handler by calling the func for each request and handling returned errors and results.
func (*HandlerWithErrorConfigurer) Handle ¶
func (h *HandlerWithErrorConfigurer) Handle(ctx context.Context, conn *Conn, req *Request)
Handle implements Handler.
func (*HandlerWithErrorConfigurer) SuppressErrClosed ¶
func (h *HandlerWithErrorConfigurer) SuppressErrClosed() Handler
SuppressErrClosed makes the handler suppress jsonrpc2.ErrClosed errors from being logged. The original handler `h` is returned.
This is optional because only in some cases is this behavior desired. For example, a handler that serves end-user connections may not want to log ErrClosed because it just indicates the end-user connection has gone away for any reason (they could have lost wifi connection, are no longer interested in the request and closed the connection, etc) and as such it would be log spam, whereas a handler that serves internal connections would never expect connections to go away unexpectedly (which could indicate service degradation, etc) and as such ErrClosed should always be logged.
type ID ¶
type ID struct { // At most one of Num or Str may be nonzero. If both are zero // valued, then IsNum specifies which field's value is to be used // as the ID. Num uint64 Str string // IsString controls whether the Num or Str field's value should be // used as the ID, when both are zero valued. It must always be // set to true if the request ID is a string. IsString bool }
ID represents a JSON-RPC 2.0 request ID, which may be either a string or number (or null, which is unsupported).
func (ID) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (*ID) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type JSONRPC2 ¶
type JSONRPC2 interface { // Call issues a standard request (http://www.jsonrpc.org/specification#request_object). Call(ctx context.Context, method string, params, result interface{}, opt ...CallOption) error // Notify issues a notification request (http://www.jsonrpc.org/specification#notification). Notify(ctx context.Context, method string, params interface{}, opt ...CallOption) error // Close closes the underlying connection, if it exists. Close() error }
JSONRPC2 describes an interface for issuing requests that speak the JSON-RPC 2 protocol. It isn't really necessary for this package itself, but is useful for external users that use the interface as an API boundary.
type Logger ¶
type Logger interface {
Printf(format string, v ...interface{})
}
Logger interface implements one method - Printf. You can use the stdlib logger *log.Logger
type ObjectCodec ¶
type ObjectCodec interface { // WriteObject writes a JSON-RPC 2.0 object to the stream. WriteObject(stream io.Writer, obj interface{}) error // ReadObject reads the next JSON-RPC 2.0 object from the stream // and stores it in the value pointed to by v. ReadObject(stream *bufio.Reader, v interface{}) error }
An ObjectCodec specifies how to encode and decode a JSON-RPC 2.0 object in a stream.
type ObjectStream ¶
type ObjectStream interface { // WriteObject writes a JSON-RPC 2.0 object to the stream. WriteObject(obj interface{}) error // ReadObject reads the next JSON-RPC 2.0 object from the stream // and stores it in the value pointed to by v. ReadObject(v interface{}) error io.Closer }
An ObjectStream is a bidirectional stream of JSON-RPC 2.0 objects.
func NewBufferedStream ¶
func NewBufferedStream(conn io.ReadWriteCloser, codec ObjectCodec) ObjectStream
NewBufferedStream creates a buffered stream from a network connection (or other similar interface). The underlying objectStream is used to produce the bytes to write to the stream for the JSON-RPC 2.0 objects.
func NewPlainObjectStream ¶ added in v0.2.0
func NewPlainObjectStream(conn io.ReadWriteCloser) ObjectStream
NewPlainObjectStream creates a buffered stream from a network connection (or other similar interface). The underlying objectStream produces plain JSON-RPC 2.0 objects without a header.
type PlainObjectCodec
deprecated
type PlainObjectCodec struct {
// contains filtered or unexported fields
}
PlainObjectCodec reads/writes plain JSON-RPC 2.0 objects without a header.
Deprecated: use NewPlainObjectStream
func (PlainObjectCodec) ReadObject ¶
func (c PlainObjectCodec) ReadObject(stream *bufio.Reader, v interface{}) error
ReadObject implements ObjectCodec.
func (PlainObjectCodec) WriteObject ¶
func (c PlainObjectCodec) WriteObject(stream io.Writer, v interface{}) error
WriteObject implements ObjectCodec.
type Request ¶
type Request struct { Method string `json:"method"` Params *json.RawMessage `json:"params,omitempty"` ID ID `json:"id"` Notif bool `json:"-"` // Meta optionally provides metadata to include in the request. // // NOTE: It is not part of spec. However, it is useful for propagating // tracing context, etc. Meta *json.RawMessage `json:"meta,omitempty"` // ExtraFields optionally adds fields to the root of the JSON-RPC request. // // NOTE: It is not part of the spec, but there are other protocols based on // JSON-RPC 2 that require it. ExtraFields []RequestField `json:"-"` }
Request represents a JSON-RPC request or notification. See http://www.jsonrpc.org/specification#request_object and http://www.jsonrpc.org/specification#notification.
func (Request) MarshalJSON ¶
MarshalJSON implements json.Marshaler and adds the "jsonrpc":"2.0" property.
func (*Request) SetExtraField ¶ added in v0.2.0
SetExtraField adds an entry to r.ExtraFields, so that it is added to the JSON encoding of the request, as a way to add arbitrary extensions to JSON RPC 2.0. If JSON marshaling fails, it returns an error.
func (*Request) SetMeta ¶
SetMeta sets r.Meta to the JSON encoding of v. If JSON marshaling fails, it returns an error.
func (*Request) SetParams ¶
SetParams sets r.Params to the JSON encoding of v. If JSON marshaling fails, it returns an error.
func (*Request) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type RequestField ¶ added in v0.2.0
type RequestField struct { Name string Value interface{} }
RequestField is a top-level field that can be added to the JSON-RPC request.
type Response ¶
type Response struct { ID ID `json:"id"` Result *json.RawMessage `json:"result,omitempty"` Error *Error `json:"error,omitempty"` // Meta optionally provides metadata to include in the response. // // NOTE: It is not part of spec. However, it is useful for propagating // tracing context, etc. Meta *json.RawMessage `json:"meta,omitempty"` }
Response represents a JSON-RPC response. See http://www.jsonrpc.org/specification#response_object.
func (Response) MarshalJSON ¶
MarshalJSON implements json.Marshaler and adds the "jsonrpc":"2.0" property.
func (*Response) SetResult ¶
SetResult sets r.Result to the JSON representation of v. If JSON marshaling fails, it returns an error.
func (*Response) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type VSCodeObjectCodec ¶
type VSCodeObjectCodec struct{}
VSCodeObjectCodec reads/writes JSON-RPC 2.0 objects with Content-Length and Content-Type headers, as specified by https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#base-protocol.
func (VSCodeObjectCodec) ReadObject ¶
func (VSCodeObjectCodec) ReadObject(stream *bufio.Reader, v interface{}) error
ReadObject implements ObjectCodec.
func (VSCodeObjectCodec) WriteObject ¶
func (VSCodeObjectCodec) WriteObject(stream io.Writer, obj interface{}) error
WriteObject implements ObjectCodec.
type VarintObjectCodec ¶
type VarintObjectCodec struct{}
VarintObjectCodec reads/writes JSON-RPC 2.0 objects with a varint header that encodes the byte length.
func (VarintObjectCodec) ReadObject ¶
func (VarintObjectCodec) ReadObject(stream *bufio.Reader, v interface{}) error
ReadObject implements ObjectCodec.
func (VarintObjectCodec) WriteObject ¶
func (VarintObjectCodec) WriteObject(stream io.Writer, obj interface{}) error
WriteObject implements ObjectCodec.