Documentation

Overview

    Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. https://www.jsonrpc.org/specification It is intended to be compatible with other implementations at the wire level.

    Index

    Constants

    View Source
    const (
    	// Send indicates the message is outgoing.
    	Send = Direction(true)
    	// Receive indicates the message is incoming.
    	Receive = Direction(false)
    )
    View Source
    const (
    	// CodeUnknownError should be used for all non coded errors.
    	CodeUnknownError = -32001
    	// CodeParseError is used when invalid JSON was received by the server.
    	CodeParseError = -32700
    	//CodeInvalidRequest is used when the JSON sent is not a valid Request object.
    	CodeInvalidRequest = -32600
    	// CodeMethodNotFound should be returned by the handler when the method does
    	// not exist / is not available.
    	CodeMethodNotFound = -32601
    	// CodeInvalidParams should be returned by the handler when method
    	// parameter(s) were invalid.
    	CodeInvalidParams = -32602
    	// CodeInternalError is not currently returned but defined for completeness.
    	CodeInternalError = -32603
    
    	//CodeServerOverloaded is returned when a message was refused due to a
    	//server being temporarily unable to accept any new messages.
    	CodeServerOverloaded = -32000
    )

    Variables

    This section is empty.

    Functions

    This section is empty.

    Types

    type Conn

    type Conn struct {
    	// contains filtered or unexported fields
    }

      Conn is a JSON RPC 2 client server connection. Conn is bidirectional; it does not have a designated server or client end.

      func NewConn

      func NewConn(s Stream) *Conn

        NewConn creates a new connection object around the supplied stream. You must call Run for the connection to be active.

        func (*Conn) AddHandler

        func (c *Conn) AddHandler(handler Handler)

          AddHandler adds a new handler to the set the connection will invoke. Handlers are invoked in the reverse order of how they were added, this allows the most recent addition to be the first one to attempt to handle a message.

          func (*Conn) Call

          func (c *Conn) Call(ctx context.Context, method string, params, result interface{}) (err error)

            Call sends a request over the connection and then waits for a response. If the response is not an error, it will be decoded into result. result must be of a type you an pass to json.Unmarshal.

            func (*Conn) Cancel

            func (c *Conn) Cancel(id ID)

              Cancel cancels a pending Call on the server side. The call is identified by its id. JSON RPC 2 does not specify a cancel message, so cancellation support is not directly wired in. This method allows a higher level protocol to choose how to propagate the cancel.

              func (*Conn) Notify

              func (c *Conn) Notify(ctx context.Context, method string, params interface{}) (err error)

                Notify is called to send a notification request over the connection. It will return as soon as the notification has been sent, as no response is possible.

                func (*Conn) Run

                func (c *Conn) Run(runCtx context.Context) error

                  Run blocks until the connection is terminated, and returns any error that caused the termination. It must be called exactly once for each Conn. It returns only when the reader is closed or there is an error in the stream.

                  type Direction

                  type Direction bool

                    Direction is used to indicate to a logger whether the logged message was being sent or received.

                    func (Direction) String

                    func (d Direction) String() string

                    type EmptyHandler

                    type EmptyHandler struct{}

                    func (EmptyHandler) Cancel

                    func (EmptyHandler) Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool

                    func (EmptyHandler) Deliver

                    func (EmptyHandler) Deliver(ctx context.Context, r *Request, delivered bool) bool

                    func (EmptyHandler) Done

                    func (EmptyHandler) Done(ctx context.Context, err error)

                    func (EmptyHandler) Error

                    func (EmptyHandler) Error(ctx context.Context, err error)

                    func (EmptyHandler) Read

                    func (EmptyHandler) Read(ctx context.Context, bytes int64) context.Context

                    func (EmptyHandler) Request

                    func (EmptyHandler) Request(ctx context.Context, direction Direction, r *WireRequest) context.Context

                    func (EmptyHandler) Response

                    func (EmptyHandler) Response(ctx context.Context, direction Direction, r *WireResponse) context.Context

                    func (EmptyHandler) Wrote

                    func (EmptyHandler) Wrote(ctx context.Context, bytes int64) context.Context

                    type Error

                    type Error struct {
                    	// Code is an error code indicating the type of failure.
                    	Code int64 `json:"code"`
                    	// Message is a short description of the error.
                    	Message string `json:"message"`
                    	// Data is optional structured data containing additional information about the error.
                    	Data *json.RawMessage `json:"data"`
                    }

                      Error represents a structured error in a Response.

                      func NewErrorf

                      func NewErrorf(code int64, format string, args ...interface{}) *Error

                        NewErrorf builds a Error struct for the suppied message and code. If args is not empty, message and args will be passed to Sprintf.

                        func (*Error) Error

                        func (err *Error) Error() string

                        type Handler

                        type Handler interface {
                        	// Deliver is invoked to handle incoming requests.
                        	// If the request returns false from IsNotify then the Handler must eventually
                        	// call Reply on the Conn with the supplied request.
                        	// Handlers are called synchronously, they should pass the work off to a go
                        	// routine if they are going to take a long time.
                        	// If Deliver returns true all subsequent handlers will be invoked with
                        	// delivered set to true, and should not attempt to deliver the message.
                        	Deliver(ctx context.Context, r *Request, delivered bool) bool
                        
                        	// Cancel is invoked for cancelled outgoing requests.
                        	// It is okay to use the connection to send notifications, but the context will
                        	// be in the cancelled state, so you must do it with the background context
                        	// instead.
                        	// If Cancel returns true all subsequent handlers will be invoked with
                        	// cancelled set to true, and should not attempt to cancel the message.
                        	Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool
                        
                        	// Request is called near the start of processing any request.
                        	Request(ctx context.Context, direction Direction, r *WireRequest) context.Context
                        	// Response is called near the start of processing any response.
                        	Response(ctx context.Context, direction Direction, r *WireResponse) context.Context
                        	// Done is called when any request is fully processed.
                        	// For calls, this means the response has also been processed, for notifies
                        	// this is as soon as the message has been written to the stream.
                        	// If err is set, it implies the request failed.
                        	Done(ctx context.Context, err error)
                        	// Read is called with a count each time some data is read from the stream.
                        	// The read calls are delayed until after the data has been interpreted so
                        	// that it can be attributed to a request/response.
                        	Read(ctx context.Context, bytes int64) context.Context
                        	// Wrote is called each time some data is written to the stream.
                        	Wrote(ctx context.Context, bytes int64) context.Context
                        	// Error is called with errors that cannot be delivered through the normal
                        	// mechanisms, for instance a failure to process a notify cannot be delivered
                        	// back to the other party.
                        	Error(ctx context.Context, err error)
                        }

                          Handler is the interface used to hook into the mesage handling of an rpc connection.

                          type ID

                          type ID struct {
                          	Name   string
                          	Number int64
                          }

                            ID is a Request identifier. Only one of either the Name or Number members will be set, using the number form if the Name is the empty string.

                            func (*ID) MarshalJSON

                            func (id *ID) MarshalJSON() ([]byte, error)

                            func (*ID) String

                            func (id *ID) String() string

                              String returns a string representation of the ID. The representation is non ambiguous, string forms are quoted, number forms are preceded by a #

                              func (*ID) UnmarshalJSON

                              func (id *ID) UnmarshalJSON(data []byte) error

                              type Request

                              type Request struct {
                              
                              	// The Wire values of the request.
                              	WireRequest
                              	// contains filtered or unexported fields
                              }

                                Request is sent to a server to represent a Call or Notify operaton.

                                func (*Request) Conn

                                func (r *Request) Conn() *Conn

                                  Conn returns the connection that created this request.

                                  func (*Request) IsNotify

                                  func (r *Request) IsNotify() bool

                                    IsNotify returns true if this request is a notification.

                                    func (*Request) Parallel

                                    func (r *Request) Parallel()

                                      Parallel indicates that the system is now allowed to process other requests in parallel with this one. It is safe to call any number of times, but must only be called from the request handling go routine. It is implied by both reply and by the handler returning.

                                      func (*Request) Reply

                                      func (r *Request) Reply(ctx context.Context, result interface{}, err error) error

                                        Reply sends a reply to the given request. It is an error to call this if request was not a call. You must call this exactly once for any given request. It should only be called from the handler go routine. If err is set then result will be ignored. If the request has not yet dropped into parallel mode it will be before this function returns.

                                        type Stream

                                        type Stream interface {
                                        	// Read gets the next message from the stream.
                                        	// It is never called concurrently.
                                        	Read(context.Context) ([]byte, int64, error)
                                        	// Write sends a message to the stream.
                                        	// It must be safe for concurrent use.
                                        	Write(context.Context, []byte) (int64, error)
                                        }

                                          Stream abstracts the transport mechanics from the JSON RPC protocol. A Conn reads and writes messages using the stream it was provided on construction, and assumes that each call to Read or Write fully transfers a single message, or returns an error.

                                          func NewHeaderStream

                                          func NewHeaderStream(in io.Reader, out io.Writer) Stream

                                            NewHeaderStream returns a Stream built on top of an io.Reader and io.Writer The messages are sent with HTTP content length and MIME type headers. This is the format used by LSP and others.

                                            func NewStream

                                            func NewStream(in io.Reader, out io.Writer) Stream

                                              NewStream returns a Stream built on top of an io.Reader and io.Writer The messages are sent with no wrapping, and rely on json decode consistency to determine message boundaries.

                                              type VersionTag

                                              type VersionTag struct{}

                                                VersionTag is a special 0 sized struct that encodes as the jsonrpc version tag. It will fail during decode if it is not the correct version tag in the stream.

                                                func (VersionTag) MarshalJSON

                                                func (VersionTag) MarshalJSON() ([]byte, error)

                                                func (VersionTag) UnmarshalJSON

                                                func (VersionTag) UnmarshalJSON(data []byte) error

                                                type WireRequest

                                                type WireRequest struct {
                                                	// VersionTag is always encoded as the string "2.0"
                                                	VersionTag VersionTag `json:"jsonrpc"`
                                                	// Method is a string containing the method name to invoke.
                                                	Method string `json:"method"`
                                                	// Params is either a struct or an array with the parameters of the method.
                                                	Params *json.RawMessage `json:"params,omitempty"`
                                                	// The id of this request, used to tie the Response back to the request.
                                                	// Will be either a string or a number. If not set, the Request is a notify,
                                                	// and no response is possible.
                                                	ID *ID `json:"id,omitempty"`
                                                }

                                                  WireRequest is sent to a server to represent a Call or Notify operaton.

                                                  type WireResponse

                                                  type WireResponse struct {
                                                  	// VersionTag is always encoded as the string "2.0"
                                                  	VersionTag VersionTag `json:"jsonrpc"`
                                                  	// Result is the response value, and is required on success.
                                                  	Result *json.RawMessage `json:"result,omitempty"`
                                                  	// Error is a structured error response if the call fails.
                                                  	Error *Error `json:"error,omitempty"`
                                                  	// ID must be set and is the identifier of the Request this is a response to.
                                                  	ID *ID `json:"id,omitempty"`
                                                  }

                                                    WireResponse is a reply to a Request. It will always have the ID field set to tie it back to a request, and will have either the Result or Error fields set depending on whether it is a success or failure response.