...

Package jsonrpc2

import "golang.org/x/tools/internal/jsonrpc2_v2"
Overview
Index

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 ▾

Variables
func EncodeMessage(msg Message) ([]byte, error)
func NewError(code int64, message string) error
type AsyncCall
    func (ac *AsyncCall) Await(ctx context.Context, result interface{}) error
    func (ac *AsyncCall) ID() ID
    func (ac *AsyncCall) IsReady() bool
type Binder
type BinderFunc
    func (f BinderFunc) Bind(ctx context.Context, c *Connection) ConnectionOptions
type Connection
    func Dial(ctx context.Context, dialer Dialer, binder Binder) (*Connection, error)
    func (c *Connection) Call(ctx context.Context, method string, params interface{}) *AsyncCall
    func (c *Connection) Cancel(id ID)
    func (c *Connection) Close() error
    func (c *Connection) Notify(ctx context.Context, method string, params interface{}) (err error)
    func (c *Connection) Respond(id ID, result interface{}, err error) error
    func (c *Connection) Wait() error
type ConnectionOptions
    func (o ConnectionOptions) Bind(context.Context, *Connection) ConnectionOptions
type Dialer
    func NetDialer(network, address string, nd net.Dialer) Dialer
type Framer
    func HeaderFramer() Framer
    func RawFramer() Framer
type Handler
type HandlerFunc
    func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error)
type ID
    func Int64ID(i int64) ID
    func StringID(s string) ID
    func (id ID) IsValid() bool
    func (id ID) Raw() interface{}
type Listener
    func NetListener(ctx context.Context, network, address string, options NetListenOptions) (Listener, error)
    func NetPipeListener(ctx context.Context) (Listener, error)
    func NewIdleListener(timeout time.Duration, wrap Listener) Listener
type Message
    func DecodeMessage(data []byte) (Message, error)
type NetListenOptions
type Preempter
type PreempterFunc
    func (f PreempterFunc) Preempt(ctx context.Context, req *Request) (interface{}, error)
type Reader
type Request
    func NewCall(id ID, method string, params interface{}) (*Request, error)
    func NewNotification(method string, params interface{}) (*Request, error)
    func (msg *Request) IsCall() bool
type Response
    func NewResponse(id ID, result interface{}, rerr error) (*Response, error)
type Server
    func NewServer(ctx context.Context, listener Listener, binder Binder) *Server
    func (s *Server) Shutdown()
    func (s *Server) Wait() error
type WireError
    func (err *WireError) Error() string
    func (err *WireError) Is(other error) bool
type Writer

Package files

conn.go frame.go jsonrpc2.go messages.go net.go serve.go serve_go116.go wire.go

Variables

var (
    // ErrIdleTimeout is returned when serving timed out waiting for new connections.
    ErrIdleTimeout = errors.New("timed out waiting for new connections")

    // ErrNotHandled is returned from a Handler or Preempter to indicate it did
    // not handle the request.
    //
    // If a Handler returns ErrNotHandled, the server replies with
    // ErrMethodNotFound.
    ErrNotHandled = errors.New("JSON RPC not handled")

    // ErrAsyncResponse is returned from a handler to indicate it will generate a
    // response asynchronously.
    //
    // ErrAsyncResponse must not be returned for notifications,
    // which do not receive responses.
    ErrAsyncResponse = errors.New("JSON RPC asynchronous response")
)
var (
    // ErrParse is used when invalid JSON was received by the server.
    ErrParse = NewError(-32700, "JSON RPC parse error")
    // ErrInvalidRequest is used when the JSON sent is not a valid Request object.
    ErrInvalidRequest = NewError(-32600, "JSON RPC invalid request")
    // ErrMethodNotFound should be returned by the handler when the method does
    // not exist / is not available.
    ErrMethodNotFound = NewError(-32601, "JSON RPC method not found")
    // ErrInvalidParams should be returned by the handler when method
    // parameter(s) were invalid.
    ErrInvalidParams = NewError(-32602, "JSON RPC invalid params")
    // ErrInternal indicates a failure to process a call correctly
    ErrInternal = NewError(-32603, "JSON RPC internal error")

    // ErrServerOverloaded is returned when a message was refused due to a
    // server being temporarily unable to accept any new messages.
    ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded")
    // ErrUnknown should be used for all non coded errors.
    ErrUnknown = NewError(-32001, "JSON RPC unknown error")
    // ErrServerClosing is returned for calls that arrive while the server is closing.
    ErrServerClosing = NewError(-32002, "JSON RPC server is closing")
    // ErrClientClosing is a dummy error returned for calls initiated while the client is closing.
    ErrClientClosing = NewError(-32003, "JSON RPC client is closing")
)

func EncodeMessage

func EncodeMessage(msg Message) ([]byte, error)

func NewError

func NewError(code int64, message string) error

NewError returns an error that will encode on the wire correctly. The standard codes are made available from this package, this function should only be used to build errors for application specific codes as allowed by the specification.

type AsyncCall

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

func (*AsyncCall) Await

func (ac *AsyncCall) Await(ctx context.Context, result interface{}) error

Await waits for (and decodes) the results of a Call. The response will be unmarshaled from JSON into the result.

func (*AsyncCall) ID

func (ac *AsyncCall) ID() ID

ID used for this call. This can be used to cancel the call if needed.

func (*AsyncCall) IsReady

func (ac *AsyncCall) IsReady() bool

IsReady can be used to check if the result is already prepared. This is guaranteed to return true on a result for which Await has already returned, or a call that failed to send in the first place.

type Binder

Binder builds a connection configuration. This may be used in servers to generate a new configuration per connection. ConnectionOptions itself implements Binder returning itself unmodified, to allow for the simple cases where no per connection information is needed.

type Binder interface {
    // Bind returns the ConnectionOptions to use when establishing the passed-in
    // Connection.
    //
    // The connection is not ready to use when Bind is called,
    // but Bind may close it without reading or writing to it.
    Bind(context.Context, *Connection) ConnectionOptions
}

type BinderFunc

A BinderFunc implements the Binder interface for a standalone Bind function.

type BinderFunc func(context.Context, *Connection) ConnectionOptions

func (BinderFunc) Bind

func (f BinderFunc) Bind(ctx context.Context, c *Connection) ConnectionOptions

type Connection

Connection manages the jsonrpc2 protocol, connecting responses back to their calls. Connection is bidirectional; it does not have a designated server or client end.

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

func Dial

func Dial(ctx context.Context, dialer Dialer, binder Binder) (*Connection, error)

Dial uses the dialer to make a new connection, wraps the returned reader and writer using the framer to make a stream, and then builds a connection on top of that stream using the binder.

The returned Connection will operate independently using the Preempter and/or Handler provided by the Binder, and will release its own resources when the connection is broken, but the caller may Close it earlier to stop accepting (or sending) new requests.

func (*Connection) Call

func (c *Connection) Call(ctx context.Context, method string, params interface{}) *AsyncCall

Call invokes the target method and returns an object that can be used to await the response. The params will be marshaled to JSON before sending over the wire, and will be handed to the method invoked. You do not have to wait for the response, it can just be ignored if not needed. If sending the call failed, the response will be ready and have the error in it.

func (*Connection) Cancel

func (c *Connection) Cancel(id ID)

Cancel cancels the Context passed to the Handle call for the inbound message with the given ID.

Cancel will not complain if the ID is not a currently active message, and it will not cause any messages that have not arrived yet with that ID to be cancelled.

func (*Connection) Close

func (c *Connection) Close() error

Close stops accepting new requests, waits for in-flight requests and enqueued Handle calls to complete, and then closes the underlying stream.

After the start of a Close, notification requests (that lack IDs and do not receive responses) will continue to be passed to the Preempter, but calls with IDs will receive immediate responses with ErrServerClosing, and no new requests (not even notifications!) will be enqueued to the Handler.

func (*Connection) Notify

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

Notify invokes the target method but does not wait for a response. The params will be marshaled to JSON before sending over the wire, and will be handed to the method invoked.

func (*Connection) Respond

func (c *Connection) Respond(id ID, result interface{}, err error) error

Respond delivers a response to an incoming Call.

Respond must be called exactly once for any message for which a handler returns ErrAsyncResponse. It must not be called for any other message.

func (*Connection) Wait

func (c *Connection) Wait() error

Wait blocks until the connection is fully closed, but does not close it.

type ConnectionOptions

ConnectionOptions holds the options for new connections.

type ConnectionOptions struct {
    // Framer allows control over the message framing and encoding.
    // If nil, HeaderFramer will be used.
    Framer Framer
    // Preempter allows registration of a pre-queue message handler.
    // If nil, no messages will be preempted.
    Preempter Preempter
    // Handler is used as the queued message handler for inbound messages.
    // If nil, all responses will be ErrNotHandled.
    Handler Handler
    // OnInternalError, if non-nil, is called with any internal errors that occur
    // while serving the connection, such as protocol errors or invariant
    // violations. (If nil, internal errors result in panics.)
    OnInternalError func(error)
}

func (ConnectionOptions) Bind

func (o ConnectionOptions) Bind(context.Context, *Connection) ConnectionOptions

Bind returns the options unmodified.

type Dialer

Dialer is used by clients to dial a server.

type Dialer interface {
    // Dial returns a new communication byte stream to a listening server.
    Dial(ctx context.Context) (io.ReadWriteCloser, error)
}

func NetDialer

func NetDialer(network, address string, nd net.Dialer) Dialer

NetDialer returns a Dialer using the supplied standard network dialer.

type Framer

Framer wraps low level byte readers and writers into jsonrpc2 message readers and writers. It is responsible for the framing and encoding of messages into wire form.

type Framer interface {
    // Reader wraps a byte reader into a message reader.
    Reader(rw io.Reader) Reader
    // Writer wraps a byte writer into a message writer.
    Writer(rw io.Writer) Writer
}

func HeaderFramer

func HeaderFramer() Framer

HeaderFramer returns a new Framer. The messages are sent with HTTP content length and MIME type headers. This is the format used by LSP and others.

func RawFramer

func RawFramer() Framer

RawFramer returns a new Framer. The messages are sent with no wrapping, and rely on json decode consistency to determine message boundaries.

type Handler

Handler handles messages on a connection.

type Handler interface {
    // Handle is invoked sequentially for each incoming request that has not
    // already been handled by a Preempter.
    //
    // If the Request has a nil ID, Handle must return a nil result,
    // and any error may be logged but will not be reported to the caller.
    //
    // If the Request has a non-nil ID, Handle must return either a
    // non-nil, JSON-marshalable result, or a non-nil error.
    //
    // The Context passed to Handle will be canceled if the
    // connection is broken or the request is canceled or completed.
    // (If Handle returns ErrAsyncResponse, ctx will remain uncanceled
    // until either Cancel or Respond is called for the request's ID.)
    Handle(ctx context.Context, req *Request) (result interface{}, err error)
}

type HandlerFunc

A HandlerFunc implements the Handler interface for a standalone Handle function.

type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error)

func (HandlerFunc) Handle

func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error)

type ID

ID is a Request identifier.

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

func Int64ID

func Int64ID(i int64) ID

Int64ID creates a new integer request identifier.

func StringID

func StringID(s string) ID

StringID creates a new string request identifier.

func (ID) IsValid

func (id ID) IsValid() bool

IsValid returns true if the ID is a valid identifier. The default value for ID will return false.

func (ID) Raw

func (id ID) Raw() interface{}

Raw returns the underlying value of the ID.

type Listener

Listener is implemented by protocols to accept new inbound connections.

type Listener interface {
    // Accept accepts an inbound connection to a server.
    // It blocks until either an inbound connection is made, or the listener is closed.
    Accept(context.Context) (io.ReadWriteCloser, error)

    // Close closes the listener.
    // Any blocked Accept or Dial operations will unblock and return errors.
    Close() error

    // Dialer returns a dialer that can be used to connect to this listener
    // locally.
    // If a listener does not implement this it will return nil.
    Dialer() Dialer
}

func NetListener

func NetListener(ctx context.Context, network, address string, options NetListenOptions) (Listener, error)

NetListener returns a new Listener that listens on a socket using the net package.

func NetPipeListener

func NetPipeListener(ctx context.Context) (Listener, error)

NetPipeListener returns a new Listener that listens using net.Pipe. It is only possibly to connect to it using the Dialer returned by the Dialer method, each call to that method will generate a new pipe the other side of which will be returned from the Accept call.

func NewIdleListener

func NewIdleListener(timeout time.Duration, wrap Listener) Listener

NewIdleListener wraps a listener with an idle timeout.

When there are no active connections for at least the timeout duration, calls to Accept will fail with ErrIdleTimeout.

A connection is considered inactive as soon as its Close method is called.

type Message

Message is the interface to all jsonrpc2 message types. They share no common functionality, but are a closed set of concrete types that are allowed to implement this interface. The message types are *Request and *Response.

type Message interface {
    // contains filtered or unexported methods
}

func DecodeMessage

func DecodeMessage(data []byte) (Message, error)

type NetListenOptions

NetListenOptions is the optional arguments to the NetListen function.

type NetListenOptions struct {
    NetListenConfig net.ListenConfig
    NetDialer       net.Dialer
}

type Preempter

Preempter handles messages on a connection before they are queued to the main handler. Primarily this is used for cancel handlers or notifications for which out of order processing is not an issue.

type Preempter interface {
    // Preempt is invoked for each incoming request before it is queued for handling.
    //
    // If Preempt returns ErrNotHandled, the request will be queued,
    // and eventually passed to a Handle call.
    //
    // Otherwise, the result and error are processed as if returned by Handle.
    //
    // Preempt must not block. (The Context passed to it is for Values only.)
    Preempt(ctx context.Context, req *Request) (result interface{}, err error)
}

type PreempterFunc

A PreempterFunc implements the Preempter interface for a standalone Preempt function.

type PreempterFunc func(ctx context.Context, req *Request) (interface{}, error)

func (PreempterFunc) Preempt

func (f PreempterFunc) Preempt(ctx context.Context, req *Request) (interface{}, error)

type Reader

Reader abstracts the transport mechanics from the JSON RPC protocol. A Conn reads messages from the reader it was provided on construction, and assumes that each call to Read fully transfers a single message, or returns an error. A reader is not safe for concurrent use, it is expected it will be used by a single Conn in a safe manner.

type Reader interface {
    // Read gets the next message from the stream.
    Read(context.Context) (Message, int64, error)
}

type Request

Request is a Message sent to a peer to request behavior. If it has an ID it is a call, otherwise it is a notification.

type Request struct {
    // ID of this request, used to tie the Response back to the request.
    // This will be nil for notifications.
    ID ID
    // Method is a string containing the method name to invoke.
    Method string
    // Params is either a struct or an array with the parameters of the method.
    Params json.RawMessage
}

func NewCall

func NewCall(id ID, method string, params interface{}) (*Request, error)

NewCall constructs a new Call message for the supplied ID, method and parameters.

func NewNotification

func NewNotification(method string, params interface{}) (*Request, error)

NewNotification constructs a new Notification message for the supplied method and parameters.

func (*Request) IsCall

func (msg *Request) IsCall() bool

type Response

Response is a Message used as a reply to a call Request. It will have the same ID as the call it is a response to.

type Response struct {
    // result is the content of the response.
    Result json.RawMessage
    // err is set only if the call failed.
    Error error
    // id of the request this is a response to.
    ID ID
}

func NewResponse

func NewResponse(id ID, result interface{}, rerr error) (*Response, error)

NewResponse constructs a new Response message that is a reply to the supplied. If err is set result may be ignored.

type Server

Server is a running server that is accepting incoming connections.

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

func NewServer

func NewServer(ctx context.Context, listener Listener, binder Binder) *Server

NewServer starts a new server listening for incoming connections and returns it. This returns a fully running and connected server, it does not block on the listener. You can call Wait to block on the server, or Shutdown to get the sever to terminate gracefully. To notice incoming connections, use an intercepting Binder.

func (*Server) Shutdown

func (s *Server) Shutdown()

Shutdown informs the server to stop accepting new connections.

func (*Server) Wait

func (s *Server) Wait() error

Wait returns only when the server has shut down.

type WireError

WireError represents a structured error in a Response.

type WireError 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,omitempty"`
}

func (*WireError) Error

func (err *WireError) Error() string

func (*WireError) Is

func (err *WireError) Is(other error) bool

type Writer

Writer abstracts the transport mechanics from the JSON RPC protocol. A Conn writes messages using the writer it was provided on construction, and assumes that each call to Write fully transfers a single message, or returns an error. A writer is not safe for concurrent use, it is expected it will be used by a single Conn in a safe manner.

type Writer interface {
    // Write sends a message to the stream.
    Write(context.Context, Message) (int64, error)
}