jsonrpc

package module
v0.0.0-...-931966b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2020 License: EPL-2.0 Imports: 8 Imported by: 13

README

Websocket API

JSON RPC 2.0 protocol is used for client-server communication, but:

  • params is always json object(never array)
  • server to client notifications are treated as Events

the apis include some of the following fields:

{
  "jsonrpc" : "2.0",
  "method": "...",
  "id": "...",
  "params": { },
  "error" : { },
  "result" : { }
}

these fields are part of the protocol so they are not documented.

Websocket messages order

The order is respected

Message fragments MUST be delivered to the recipient in the order sent by the sender.

Helpful Sources

Documentation

Overview

Package jsonrpc provides lightweight implementation of JSONRPC 2.0 protocol. See http://www.jsonrpc.org/specification.

- the implementation does not support 'Batch' operations. - the implementation supports 2.0 version only. - the implementation uses 2.0 version for those requests that do not specify the version.

Index

Constants

View Source
const (
	// ParseErrorCode indicates that invalid JSON was received by the server.
	ParseErrorCode = -32700

	// InvalidRequestErrorCode indicates that request object is not valid,
	// fails when route decoder can't decode params.
	InvalidRequestErrorCode = -32600

	// MethodNotFoundErrorCode indicates that there is no route for such method.
	MethodNotFoundErrorCode = -32601

	// InvalidParamsErrorCode indicates that handler parameters are considered as not valid.
	// This error type should be returned directly from the Handle
	InvalidParamsErrorCode = -32602

	// InternalErrorCode is returned when error returned from the Route Handle is different from Error type.
	InternalErrorCode = -32603

	// TimeoutErrorCode is returned when timeout is reached where response should arrive.
	TimeoutErrorCode = -32001
)
View Source
const (
	// DefaultVersion is a version which is used by this package
	// for all the types of sent/received data.
	DefaultVersion = "2.0"

	// ConnectedNotificationMethodName notification sent by Tunnel.SayHello().
	ConnectedNotificationMethodName = "connected"

	// DefaultAllowedResponseDelay is allowed time for reply to be sent.
	// RespTransmitter waits for MethodHandler to respond to the request
	// or replies with timeout error if timeout is reached.
	// The value is experimental.
	DefaultAllowedResponseDelay = time.Minute

	// DefaultWatchQueuePeriod is how often request queue lookups requests.
	// The value is experimental.
	DefaultWatchQueuePeriod = time.Minute

	// DefaultMaxRequestHoldTimeout is how long a request stays in the queue
	// and waits for the response to come, if reply is not made in time
	// RespHandlerFunc is called with TimeoutError.
	// Note that request stays in request queue from DefaultMaxRequestHoldTimeout
	// to DefaultMaxRequestHoldTimeout + DefaultWatchQueuePeriod time.
	DefaultMaxRequestHoldTimeout = time.Minute
)

Variables

View Source
var DefaultRegistry = NewRegistry()

DefaultRegistry is package registry, which is used by NewManagedTunnel.

View Source
var DefaultRouter = NewRouter()

DefaultRouter is a default package router. It might be used as tunnels request handler.

Functions

func PrintRoutes

func PrintRoutes(rg []RoutesGroup)

PrintRoutes prints provided rpc routes by group.

func RegRoute

func RegRoute(r Route)

RegRoute registers route using package DefaultRouter.

func RegRoutesGroup

func RegRoutesGroup(rg RoutesGroup)

RegRoutesGroup registers routes group using package DefaultRouter.

func RegRoutesGroups

func RegRoutesGroups(rgs []RoutesGroup)

RegRoutesGroups registers routes groups using package DefaultRouter.

func Save

func Save(tun *Tunnel)

Save saves a given tunnel is the default registry.

Types

type CloseError

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

CloseError is an error which MUST be published by NativeConn implementations and used to determine the cases when tunnel job should be stopped.

func NewCloseError

func NewCloseError(err error) *CloseError

NewCloseError creates a new close error based on a given error.

type DecodeFunc

type DecodeFunc func(body []byte) (interface{}, error)

DecodeFunc used to decode route params for forth handling by HandleFunc.

func FactoryDec

func FactoryDec(create func() interface{}) DecodeFunc

FactoryDec uses given function to get an instance of object and then unmarshal params json into that object. The result of this function can be used as Route.Decode function.

type Error

type Error struct {

	// Code is the value indicating the certain error type.
	Code int `json:"code"`

	// Message is the description of this error.
	Message string `json:"message"`

	// Data any kind of data which provides additional
	// information about the error e.g. stack trace, error time.
	Data json.RawMessage `json:"data,omitempty"`
	// contains filtered or unexported fields
}

Error indicates any exceptional situation during operation execution, e.g an attempt to perform operation using invalid data.

func NewArgsError

func NewArgsError(err error) *Error

NewArgsError creates error object from provided error and sets error code InvalidParamsErrorCode.

func NewError

func NewError(code int, err error) *Error

NewError creates an error from the given error and code.

func NewErrorf

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

NewErrorf creates an error from the given code and formatted message.

type HandleFunc

type HandleFunc func(tun *Tunnel, params interface{}, t RespTransmitter)

HandleFunc used to handle route request.

func HandleRet

func HandleRet(f func(tun *Tunnel, params interface{}) (interface{}, error)) HandleFunc

HandleRet converts handle function without transmitter to the HandleFunc. Returned values will be sent with transmitter.

type MethodHandler

type MethodHandler interface {

	// Unmarshal decodes request raw request parameters
	// e.g. parses json and returns instance of structured params.
	// If the handler does not need parameters - (nil, nil) should be returned.
	// If returned error is different from nil Call is not executed.
	Unmarshal(params []byte) (interface{}, error)

	// Call calls handler of this request.
	// If no Send method is called on response transmitter instance
	// timeout error reply will be sent, unless request is notification.
	Call(tun *Tunnel, params interface{}, rt RespTransmitter)
}

MethodHandler handles a certain method. First raw request parameters are decoded using Unmarshal function and then if call returned no error handle is called.

type NativeConn

type NativeConn interface {

	// Write writes bytes to the connection.
	Write(body []byte) error

	// Next is blocking read of incoming messages.
	// If connection is closed an error of type *jsonrpc.CloseError
	// must be returned.
	Next() ([]byte, error)

	// Closes this connection.
	Close() error
}

NativeConn provides low level interface for jsonrpc.Tunnel to communicate with native connection such as websocket.

type ReqDispatcher

type ReqDispatcher interface {

	// FindHandler must return a handler for a given method and ok=true,
	// if there is no such handler func must return ok=false
	FindHandler(method string) (MethodHandler, bool)
}

ReqDispatcher is a single handler for all the tunnel incoming requests. The main responsibility is to provide the right method handler for incoming request.

type Request

type Request struct {

	// Version of this request e.g. '2.0'.
	//
	// The version field is required.
	Version string `json:"jsonrpc"`

	// Method is the name which will be proceeded by this request.
	//
	// Must not start with "rpc" + (U+002E or ASCII 46), such methods are
	// reserved for rpc internal methods and extensions.
	//
	// The method field is required.
	Method string `json:"method"`

	// The unique identifier of this operation request.
	// If a client needs to identify the result of the operation execution,
	// the id should be passed by the client, then it is guaranteed
	// that the client will receive the result frame with the same id.
	// The uniqueness of the identifier must be controlled by the client,
	// if client doesn't specify the identifier in the operation call,
	// the response won't contain the identifier as well.
	//
	// It is preferable to specify identifier for those calls which may
	// either validate data, or produce such information which can't be
	// identified by itself.
	//
	// If id is set then the object is Request otherwise it's Notification.
	ID interface{} `json:"id,omitempty"`

	// Params parameters which are needed for operation execution.
	// Params are either json array or json object, for json objects
	// names of the parameters are case sensitive.
	//
	// The params field is optional.
	Params json.RawMessage `json:"params"`
}

Request is the identified call of the method. Server MUST eventually reply on the response and include the same identifier value as the request provides.

Request without id is Notification. Server MUST NOT reply to Notification.

func (*Request) IsNotification

func (r *Request) IsNotification() bool

IsNotification tests if this request is notification(id is not set).

type RespHandleFunc

type RespHandleFunc func(result []byte, err *Error)

RespHandleFunc used to handle requests responses. The request is sent by one of the Request, RequestBare methods. If the response doesn't arrive in time the handler func will be called with an error with code TimeoutErrorCode.

type RespTransmitter

type RespTransmitter interface {

	// Send sends jsonrpc response with a given result in body.
	// This function can be called only once on one transmitter instance.
	Send(result interface{})

	// SendError sends jsonrpc response with a given error in body.
	// This function can be called only once on one transmitter instance.
	SendError(err *Error)
}

RespTransmitter provides interface which allows to respond to request from any method handler. The implementation must guarantee that reply will be eventually sent for those requests which are not notifications. Functions Send & SendError MUST not be called both or twice on the same instance of transmitter. The request id MUST be included to the response.

type Response

type Response struct {

	// Version of this response e.g. '2.0'.
	// The version is required.
	Version string `json:"jsonrpc"`

	// The operation call identifier, will be set only
	// if the operation contains it.
	ID interface{} `json:"id,omitempty"`

	// Result is the result of the method call.
	// Result can be anything determined by the operation(method).
	// Result and Error are mutually exclusive.
	Result json.RawMessage `json:"result,omitempty"`

	// Result and Error are mutually exclusive.
	// Present only if the operation execution fails due to an error.
	Error *Error `json:"error,omitempty"`
}

Response is a reply on a certain request, which represents the result of the certain operation execution. Response MUST provide the same identifier as the request which forced it.

type Route

type Route struct {

	// Method is the operation name like defined by Request.Method.
	Method string

	// Decode used for decoding raw request parameters
	// into the certain object. If decoding is okay, then
	// decoded value will be passed to the Handle
	// of this request route, so it is up to the route
	// - to define type safe couple of Decode & Handle.
	Decode DecodeFunc

	// Handle handler for decoded request parameters.
	// If handler function can't perform the operation then
	// handler function should either return an error, or
	// send it directly within transmitter#SendError func.
	// Params is a value returned from the Decode.
	Handle HandleFunc
}

Route defines named operation and its handler.

func (Route) Call

func (r Route) Call(tun *Tunnel, params interface{}, rt RespTransmitter)

Call handles request using Route.Handle.

func (Route) Unmarshal

func (r Route) Unmarshal(params []byte) (interface{}, error)

Unmarshal unpacks raw request params using route.Decode.

type Router

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

Router is a simple request dispatcher.

func NewRouter

func NewRouter() *Router

NewRouter returns a new router.

func (*Router) FindHandler

func (r *Router) FindHandler(method string) (MethodHandler, bool)

FindHandler finds a route for a given method.

func (*Router) Register

func (r *Router) Register(route Route)

Register registers a new route in this router.

func (*Router) RegisterGroup

func (r *Router) RegisterGroup(group RoutesGroup)

RegisterGroup registers a whole routes group.

func (*Router) RegisterGroups

func (r *Router) RegisterGroups(groups []RoutesGroup)

RegisterGroups registers

type RoutesGroup

type RoutesGroup struct {

	// Name is the name of this group.
	Name string

	// Items routes.
	Items []Route
}

RoutesGroup is named group of rpc routes.

type Tunnel

type Tunnel struct {

	// Attributes to store useful meta information
	Attributes map[string]string
	// contains filtered or unexported fields
}

Tunnel is high level jsonrpc transport layer which uses native connection to access low level transport routines.

func Get

func Get(id string) (*Tunnel, bool)

Get gets a single tunnel managed by default registry.

func GetTunnels

func GetTunnels() []*Tunnel

GetTunnels gets tunnels managed by default registry.

func NewManagedTunnel

func NewManagedTunnel(conn NativeConn) *Tunnel

NewManagedTunnel creates a new tunnel using given connection and DefaultRouter as request dispatcher, then the tunnel is saved in default registry and Go func is called.

func NewTunnel

func NewTunnel(conn NativeConn, dispatcher ReqDispatcher) *Tunnel

NewTunnel creates a new tunnel. Use tunnel.Go() to start communication.

func Rm

func Rm(id string) (*Tunnel, bool)

Rm removes a given tunnel from the default registry.

func (*Tunnel) Close

func (tun *Tunnel) Close()

Close closes native connection and internal sources, so started go routines should be eventually stopped.

func (*Tunnel) Conn

func (tun *Tunnel) Conn() NativeConn

Conn returns the connection this tunnel is based on.

func (*Tunnel) Go

func (tun *Tunnel) Go()

Go starts this tunnel, makes it functional.

func (*Tunnel) ID

func (tun *Tunnel) ID() string

ID returns the identifier of this tunnel.

func (*Tunnel) IsClosed

func (tun *Tunnel) IsClosed() bool

IsClosed returns true if this tunnel is closed and false otherwise.

func (*Tunnel) Notify

func (tun *Tunnel) Notify(method string, params interface{}) error

Notify sends notification(request without id) using given params as its body.

func (*Tunnel) NotifyBare

func (tun *Tunnel) NotifyBare(method string) error

NotifyBare sends notification like Notify does but sends no request parameters in it.

func (*Tunnel) Request

func (tun *Tunnel) Request(method string, params interface{}, rhf RespHandleFunc) error

Request sends request marshalling a given params as its body. RespHandleFunc will be called as soon as the response arrives, or response arrival timeout reached, in that case error of type TimeoutError will be passed to the handler.

func (*Tunnel) RequestBare

func (tun *Tunnel) RequestBare(method string, rhf RespHandleFunc) error

RequestBare sends the request like Request func does but sends no params in it.

func (*Tunnel) SayHello

func (tun *Tunnel) SayHello()

SayHello sends hello notification.

type TunnelNotification

type TunnelNotification struct {

	// Time is the time channel was created.
	Time time.Time `json:"time"`

	// ChannelID is the id of the tunnel.
	// The value is the same to TunnelID, its kept for backward comp.
	ChannelID string `json:"channel"`

	// TunnelID the id of the tunnel.
	TunnelID string `json:"tunnel"`

	// Text event message.
	Text string `json:"text"`
}

TunnelNotification struct describing notification params sent by SayHello.

type TunnelRegistry

type TunnelRegistry struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

TunnelRegistry is a simple storage for tunnels.

func NewRegistry

func NewRegistry() *TunnelRegistry

NewRegistry creates a new registry.

func (*TunnelRegistry) Get

func (reg *TunnelRegistry) Get(id string) (*Tunnel, bool)

Get returns tunnel with a given id.

func (*TunnelRegistry) GetTunnels

func (reg *TunnelRegistry) GetTunnels() []*Tunnel

GetTunnels returns all the tunnels which the registry keeps.

func (*TunnelRegistry) Rm

func (reg *TunnelRegistry) Rm(id string) (*Tunnel, bool)

Rm removes tunnel with given id from the registry.

func (*TunnelRegistry) Save

func (reg *TunnelRegistry) Save(tunnel *Tunnel)

Save saves a tunnel with a given id in this registry, overrides existing one.

Directories

Path Synopsis
Package event provides lightweight primitives for event-bus-consumer communication.
Package event provides lightweight primitives for event-bus-consumer communication.
Package jsonrpcws provides implementation of jsonrpc.NativeConn based on websocket.
Package jsonrpcws provides implementation of jsonrpc.NativeConn based on websocket.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL