jsonrpc

package module
v0.0.0-...-f902a6f Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: Apache-2.0, MIT Imports: 33 Imported by: 0

README

go-jsonrpc

go.dev reference

Low Boilerplate JSON-RPC 2.0 library

Usage examples

Server
// Have a type with some exported methods
type SimpleServerHandler struct {
    n int
}

func (h *SimpleServerHandler) AddGet(in int) int {
    h.n += in
    return h.n
}

func main() {
    // create a new server instance
    rpcServer := jsonrpc.NewServer()
    
    // create a handler instance and register it
    serverHandler := &SimpleServerHandler{}
    rpcServer.Register("SimpleServerHandler", serverHandler)
    
    // rpcServer is now http.Handler which will serve jsonrpc calls to SimpleServerHandler.AddGet
    // a method with a single int param, and an int response. The server supports both http and websockets.
    
    // serve the api
    testServ := httptest.NewServer(rpcServer)
    defer testServ.Close()
	
    fmt.Println("URL: ", "ws://"+testServ.Listener.Addr().String())
    
    [..do other app stuff / wait..]
}
Client
func start() error {
    // Create a struct where each field is an exported function with signatures matching rpc calls
    var client struct {
        AddGet      func(int) int
    }
	
	// Make jsonrp populate func fields in the struct with JSONRPC calls
    closer, err := jsonrpc.NewClient(context.Background(), rpcURL, "SimpleServerHandler", &client, nil)
    if err != nil {
    	return err
    }
    defer closer()
    
    ...
    
    n := client.AddGet(10)
    // if the server is the one from the example above, n = 10

    n := client.AddGet(2)
    // if the server is the one from the example above, n = 12
}
Supported function signatures
type _ interface {
    // No Params / Return val
    Func1()
    
    // With Params
    // Note: If param types implement json.[Un]Marshaler, go-jsonrpc will use it
    Func2(param1 int, param2 string, param3 struct{A int})
    
    // Returning errors
    // * For some connection errors, go-jsonrpc will return jsonrpc.RPCConnectionError{}.
    // * RPC-returned errors will be constructed with basic errors.New(__"string message"__)
    // * JSON-RPC error codes can be mapped to typed errors with jsonrpc.Errors - https://pkg.go.dev/github.com/filecoin-project/go-jsonrpc#Errors
    // * For typed errors to work, server needs to be constructed with the `WithServerErrors`
    //   option, and the client needs to be constructed with the `WithErrors` option
    Func3() error
    
    // Returning a value
    // Note: The value must be serializable with encoding/json.
    Func4() int
    
    // Returning a value and an error
    // Note: if the handler returns an error and a non-zero value, the value will not
    //       be returned to the client - the client will see a zero value.
    Func4() (int, error)
    
    // With context
    // * Context isn't passed as JSONRPC param, instead it has a number of different uses
    // * When the context is cancelled on the client side, context cancellation should propagate to the server handler
    //   * In http mode the http request will be aborted
    //   * In websocket mode the client will send a `xrpc.cancel` with a single param containing ID of the cancelled request
    // * If the context contains an opencensus trace span, it will be propagated to the server through a
    //   `"Meta": {"SpanContext": base64.StdEncoding.EncodeToString(propagation.Binary(span.SpanContext()))}` field in
    //   the jsonrpc request
    //   
    Func5(ctx context.Context, param1 string) error
    
    // With non-json-serializable (e.g. interface) params
    // * There are client and server options which make it possible to register transformers for types
    //   to make them json-(de)serializable
    // * Server side: jsonrpc.WithParamDecoder(new(io.Reader), func(ctx context.Context, b []byte) (reflect.Value, error) { ... }
    // * Client side: jsonrpc.WithParamEncoder(new(io.Reader), func(value reflect.Value) (reflect.Value, error) { ... }
    // * For io.Reader specifically there's a simple param encoder/decoder implementation in go-jsonrpc/httpio package
    //   which will pass reader data through separate http streams on a different hanhler.
    // * Note: a similar mechanism for return value transformation isn't supported yet
    Func6(r io.Reader)
    
    // Returning a channel
    // * Only supported in websocket mode
    // * If no error is returned, the return value will be an int channelId
    // * When the server handler writes values into the channel, the client will receive `xrpc.ch.val` notifications
    //   with 2 params: [chanID: int, value: any]
    // * When the channel is closed the client will receive `xrpc.ch.close` notification with a single param: [chanId: int]
    // * The client-side channel will be closed when the websocket connection breaks; Server side will discard writes to
    //   the channel. Handlers should rely on the context to know when to stop writing to the returned channel.
    // NOTE: There is no good backpressure mechanism implemented for channels, returning values faster that the client can
    // receive them may cause memory leaks.
    Func7(ctx context.Context, param1 int, param2 string) (<-chan int, error)
}

Custom Transport Feature

The go-jsonrpc library supports creating clients with custom transport mechanisms (e.g. use for IPC). This allows for greater flexibility in how requests are sent and received, enabling the use of custom protocols, special handling of requests, or integration with other systems.

Example Usage of Custom Transport

Here is an example demonstrating how to create a custom client with a custom transport mechanism:

// Setup server
serverHandler := &SimpleServerHandler{} // some type with methods

rpcServer := jsonrpc.NewServer()
rpcServer.Register("SimpleServerHandler", serverHandler)

// Custom doRequest function
doRequest := func(ctx context.Context, body []byte) (io.ReadCloser, error) {
    reader := bytes.NewReader(body)
    pr, pw := io.Pipe()
    go func() {
        defer pw.Close()
        rpcServer.HandleRequest(ctx, reader, pw) // handle the rpc frame
    }()
    return pr, nil
}

var client struct {
    Add    func(int) error
}

// Create custom client
closer, err := jsonrpc.NewCustomClient("SimpleServerHandler", []any{&client}, doRequest)
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}
defer closer()

// Use the client
if err := client.Add(10); err != nil {
    log.Fatalf("Failed to call Add: %v", err)
}
fmt.Printf("Current value: %d\n", client.AddGet(5))
Reverse Calling Feature

The go-jsonrpc library also supports reverse calling, where the server can make calls to the client. This is useful in scenarios where the server needs to notify, request data from the client, or for subscriptions (e.g. eth_subscribe).

NOTE: Reverse calling only works in websocket mode

Example Usage of Reverse Calling

Here is an example demonstrating how to set up reverse calling:

// Define the client handler interface
type ClientHandler struct {
    CallOnClient func(int) (int, error)
}

// Define the server handler
type ServerHandler struct {}

func (h *ServerHandler) Call(ctx context.Context) error {
    revClient, ok := jsonrpc.ExtractReverseClient[ClientHandler](ctx)
    if !ok {
        return fmt.Errorf("no reverse client")
    }

    result, err := revClient.CallOnClient(7) // Multiply by 2 on client
    if err != nil {
        return fmt.Errorf("call on client: %w", err)
    }

    if result != 14 {
        return fmt.Errorf("unexpected result: %d", result)
    }

    return nil
}

// Define client handler
type RevCallTestClientHandler struct {
}

func (h *RevCallTestClientHandler) CallOnClient(a int) (int, error) {
    return a * 2, nil
}

// Setup server with reverse client capability
rpcServer := jsonrpc.NewServer(jsonrpc.WithReverseClient[ClientHandler]("Client"))
rpcServer.Register("ServerHandler", &ServerHandler{})

testServ := httptest.NewServer(rpcServer)
defer testServ.Close()

// Setup client with reverse call handler
var client struct {
    Call func() error
}

closer, err := jsonrpc.NewMergeClient(context.Background(), "ws://"+testServ.Listener.Addr().String(), "ServerHandler", []any{
    &client,
}, nil, jsonrpc.WithClientHandler("Client", &RevCallTestClientHandler{}))
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}
defer closer()

// Make a call from the client to the server, which will trigger a reverse call
if err := client.Call(); err != nil {
    log.Fatalf("Failed to call server: %v", err)
}

Options

Using method name formatters
Using WithServerMethodNameFormatter

WithServerMethodNameFormatter allows you to customize a function that formats the JSON-RPC method name, given namespace and method name.

There are four possible out-of-the-box options:

  • jsonrpc.DefaultMethodNameFormatter - default method name formatter, e.g. SimpleServerHandler.AddGet
  • jsonrpc.NewMethodNameFormatter(true, jsonrpc.LowerFirstCharCase) - method name formatter with namespace, e.g. SimpleServerHandler.addGet
  • jsonrpc.NewMethodNameFormatter(false, jsonrpc.OriginalCase) - method name formatter without namespace, e.g. AddGet
  • jsonrpc.NewMethodNameFormatter(false, jsonrpc.LowerFirstCharCase) - method name formatter without namespace and with the first char lowercased, e.g. addGet

[!NOTE]
The default method name formatter concatenates the namespace and method name with a dot. Go exported methods are capitalized, so, the method name will be capitalized as well. e.g. SimpleServerHandler.AddGet (capital "A" in "AddGet")

You can also create your own method name formatter by creating a function that implements the jsonrpc.MethodNameFormatter interface.

func main() {
	// create a new server instance with a custom separator
	rpcServer := jsonrpc.NewServer(jsonrpc.WithServerMethodNameFormatter(
		func(namespace, method string) string {
			return namespace + "_" + method
		}),
	)

	// create a handler instance and register it
	serverHandler := &SimpleServerHandler{}
	rpcServer.Register("SimpleServerHandler", serverHandler)

	// serve the api
	testServ := httptest.NewServer(rpcServer)
	defer testServ.Close()

	fmt.Println("URL: ", "ws://"+testServ.Listener.Addr().String())

	// rpc method becomes SimpleServerHandler_AddGet

    [..do other app stuff / wait..]
}
Using WithMethodNameFormatter

WithMethodNameFormatter is the client-side counterpart to WithServerMethodNameFormatter.

func main() {
    closer, err := NewMergeClient(
        context.Background(),
        "http://example.com",
        "SimpleServerHandler",
        []any{&client},
        nil,
        WithMethodNameFormatter(jsonrpc.NewMethodNameFormatter(false, OriginalCase)),
    )
    defer closer()
}
Using WithClientHandlerFormatter

Same as WithMethodNameFormatter, but for client handlers. Using it you can fully customize the JSON-RPC method name for client handlers, given namespace and method name.

func main() {
    closer, err := jsonrpc.NewMergeClient(
        context.Background(),
        "http://example.com",
        "SimpleServerHandler",
        []any{&client},
        nil,
        jsonrpc.WithMethodNameFormatter(jsonrpc.NewMethodNameFormatter(false, OriginalCase)),
        jsonrpc.WithClientHandler("Client", &RevCallTestClientHandler{}),
        jsonrpc.WithClientHandlerFormatter(jsonrpc.NewMethodNameFormatter(false, OriginalCase)),
    )
    defer closer()
}
Using method name alias

You can also create an alias for a method name. This is useful if you want to use a different method name in the JSON-RPC request than the actual method name for a specific method.

Usage of method name alias in the server
type SimpleServerHandler struct {}

func (h *SimpleServerHandler) Double(in int) int {
    return in * 2
}

// create a new server instance
rpcServer := jsonrpc.NewServer()

// create a handler instance and register it
serverHandler := &SimpleServerHandler{}
rpcServer.Register("SimpleServerHandler", serverHandler)

// create an alias for the Double method. This will allow you to call the server's Double method
// with the name "rand_myRandomAlias" in the JSON-RPC request.
rpcServer.AliasMethod("rand_myRandomAlias", "SimpleServerHandler.Double")

Usage of method name alias with client handlers
// setup the client handler
type ReverseHandler struct {}

func (h *ReverseHandler) DoubleOnClient(in int) int {
    return in * 2
}

// create a new client instance with the client handler + method name alias
closer, err := jsonrpc.NewMergeClient(
    context.Background(),
    "http://example.com",
    "SimpleServerHandler",
    []any{&client},
    nil,
    jsonrpc.WithClientHandler("Client", &ReverseHandler{}),
    // this allows the server to call the client's DoubleOnClient method using the name "rand_theClientRandomAlias" in the JSON-RPC request.
    jsonrpc.WithClientHandlerAlias("rand_theClientRandomAlias", "Client.DoubleOnClient"),
)
Usage of a struct tag to define method name alias

There are two cases where you can also use the rpc_method struct tag to define method name alias: in the client struct and in the reverse handler struct in the server.

In the client struct:

// setup the client struct
var client struct {
    AddInt func(int) int `rpc_method:"rand_aRandomAlias"`
}

// create a new client instance with the client struct that has the `rpc_method` struct tag
closer, err := jsonrpc.NewMergeClient(
    context.Background(),
    "http://example.com",
    "SimpleServerHandler",
    []any{&client},
    nil,
)

// since we defined the method name alias in the client struct, this will send a JSON-RPC request with "rand_aRandomAlias" as the method name to the
// server instead of "SimpleServerHandler.AddInt".
result, err := client.AddInt(10)

In the server's reverse handler struct:

// Define the client handler interface
type ClientHandler struct {
    CallOnClient func(int) (int, error) `rpc_method:"rand_theClientRandomAlias"`
}

// Define the server handler
type ServerHandler struct {}

func (h *ServerHandler) Call(ctx context.Context) (int, error) {
    revClient, _ := jsonrpc.ExtractReverseClient[ClientHandler](ctx)

    // Reverse call to the client.
    // Since we defined the method name alias in the client handler struct tag, this
    // will send a JSON-RPC request with "rand_theClientRandomAlias" as the method name to the
    // client instead of "Client.CallOnClient".
    result, err := revClient.CallOnClient(7)
    
    // ...
}

// Setup server with reverse client capability
rpcServer := jsonrpc.NewServer(jsonrpc.WithReverseClient[ClientHandler]("Client"))
rpcServer.Register("ServerHandler", &ServerHandler{})

Contribute

PRs are welcome!

License

Dual-licensed under MIT + Apache 2.0

Documentation

Index

Constants

View Source
const (
	ProxyTagRetry     = "retry"
	ProxyTagNotify    = "notify"
	ProxyTagRPCMethod = "rpc_method"
)
View Source
const (
	ErrNoParam     paramError = "no params when params is required"
	ErrShortParams paramError = "not enough params"
	ErrExtraParams paramError = "extra params"
	ErrNotAnArray  paramError = "param value is not an array"
)
View Source
const (
	ErrExtraOptionalParams = paramError("non-nil optional params found after a nil one")
	ErrExtraVariadicParams = paramError("variadic params found after nil optional params")
)
View Source
const DEFAULT_MAX_REQUEST_SIZE = 100 << 20 // 100 MiB

Limit request size. Ideally this limit should be specific for each field in the JSON request but as a simple defensive measure we just limit the entire HTTP body. Configured by WithMaxRequestSize.

View Source
const ErrWsExiting = cerrors.String("websocket routine exiting")
View Source
const FirstUserCode = 2

Variables

View Source
var DefaultMethodNameFormatter = NewMethodNameFormatter(true, OriginalCase)

DefaultMethodNameFormatter is a pass-through formatter with default options.

View Source
var ErrDataTooLarge = errors.New("request bigger than maximum allowed")

Functions

func ContextFrom

func ContextFrom(opts json.Options) context.Context

func ExtractReverseClient

func ExtractReverseClient[C any](ctx context.Context) (C, bool)

ExtractReverseClient will extract reverse client from context. Reverse client for the type will only be present if the server was constructed with a matching WithReverseClient option and the connection was a websocket connection. If there is no reverse client, the call will return a zero value and `false`. Otherwise a reverse client and `true` will be returned.

func HasReqCtx

func HasReqCtx(ctx context.Context) bool

func LimitReader

func LimitReader(r io.Reader, n int64) io.Reader

LimitReader returns a Reader that reads from r but stops with ErrDataTooLarge after n bytes. The underlying implementation is a *LimitedReader.

func LoadAssert

func LoadAssert[T any](loadf func(any) (any, bool), key any) (t T, ok bool)

func NewTeeLogValue

func NewTeeLogValue(r io.Reader) teeValue

func OptionsLoad

func OptionsLoad[T any](opts json.Options) (T, bool)

func OptionsStore

func OptionsStore[T any](opts json.Options, value T) json.Options

func RegisterError

func RegisterError[T error](errs Errors, code ErrorCode)

func WithClientHandler

func WithClientHandler(ns string, hnd any) func(c *Config)

func WithClientHandlerAlias

func WithClientHandlerAlias(alias, original string) func(c *Config)

WithClientHandlerAlias creates an alias for a client HANDLER method - for handlers created with WithClientHandler

func WithClientHandlerFormatter

func WithClientHandlerFormatter(namer MethodNameFormatter) func(c *Config)

Just like WithMethodNameFormatter, but for client handlers.

func WithContext

func WithContext(opts json.Options, ctx context.Context) json.Options

this is sort of black magic, but it allows us to pass context into json unmarshaling

func WithErrors

func WithErrors(es Errors) func(c *Config)

func WithHTTPClient

func WithHTTPClient(h *http.Client) func(c *Config)

func WithJsonOptions

func WithJsonOptions(opts ...json.Options) func(c *Config)

func WithLogger

func WithLogger(logger *slog.Logger) func(c *Config)

func WithMethodNameFormatter

func WithMethodNameFormatter(namer MethodNameFormatter) func(c *Config)

func WithNoReconnect

func WithNoReconnect() func(c *Config)

func WithParamMarshaler

func WithParamMarshaler[T any](fn MarshalerFunc[T]) func(c *Config)

func WithParamUnmarshaler

func WithParamUnmarshaler[T any](fn UnmarshalerFunc[*T]) func(c *ServerConfig)

func WithPingInterval

func WithPingInterval(d time.Duration) func(c *Config)

Must be < Timeout/2

func WithReconnectBackoff

func WithReconnectBackoff(minDelay, maxDelay time.Duration) func(c *Config)

func WithResultMarshaler

func WithResultMarshaler[T any](fn MarshalerFunc[T]) func(c *ServerConfig)

func WithResultUnmarshaler

func WithResultUnmarshaler[T any](fn UnmarshalerFunc[*T]) func(c *Config)

func WithTimeout

func WithTimeout(d time.Duration) func(c *Config)

func WithWebsocketDialer

func WithWebsocketDialer(d *websocket.Dialer) func(c *Config)

Types

type CaseStyle

type CaseStyle int

CaseStyle represents the case style for method names.

const (
	OriginalCase CaseStyle = iota
	LowerFirstCharCase
)

type ClientCloser

type ClientCloser func()

ClientCloser is used to close Client from further use

func NewClient

func NewClient(ctx context.Context, addr string, namespace string, handler any, requestHeader http.Header, opts ...Option) (ClientCloser, error)

NewClient creates new jsonrpc 2.0 client

handler must be pointer to a struct with function fields Returned value closes the client connection TODO: Example

func NewCustomClient

func NewCustomClient(namespace string, outs []any, doRequest func(ctx context.Context, body []byte) (io.ReadCloser, error), opts ...Option) (ClientCloser, error)

NewCustomClient is like NewMergeClient in single-request (http) mode, except it allows for a custom doRequest function

func NewCustomReaderClient

func NewCustomReaderClient(ctx context.Context, namespace string, outs []any, doRequest func(ctx context.Context, body io.ReadCloser) (io.ReadCloser, error), opts ...Option) (ClientCloser, error)

func NewMergeClient

func NewMergeClient(ctx context.Context, addr string, namespace string, outs []any, requestHeader http.Header, opts ...Option) (ClientCloser, error)

NewMergeClient is like NewClient, but allows to specify multiple structs to be filled in the same namespace, using one connection

type Config

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

func (*Config) GetHTTPClient

func (c *Config) GetHTTPClient() *http.Client

func (*Config) GetJsonOptions

func (c *Config) GetJsonOptions() json.Options

func (*Config) GetLogger

func (c *Config) GetLogger() *slog.Logger

func (*Config) GetTimeout

func (c *Config) GetTimeout() time.Duration

type ConnectionType

type ConnectionType string

ConnectionType indicates the type of connection, this is set in the context and can be retrieved with GetConnectionType.

const (
	// ConnectionTypeUnknown indicates that the connection type cannot be determined, likely because
	// it hasn't passed through an RPCServer.
	ConnectionTypeUnknown ConnectionType = "unknown"
	// ConnectionTypeHTTP indicates that the connection is an HTTP connection.
	ConnectionTypeHTTP ConnectionType = "http"
	// ConnectionTypeWS indicates that the connection is a WebSockets connection.
	ConnectionTypeWS ConnectionType = "websockets"
)

func GetConnectionType

func GetConnectionType(ctx context.Context) ConnectionType

GetConnectionType returns the connection type of the request if it was set by an RPCServer. A connection type of ConnectionTypeUnknown means that the connection type was not set.

type ErrClient

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

ErrClient is an error which occurred on the client side the library

func (*ErrClient) Error

func (e *ErrClient) Error() string

func (*ErrClient) Unwrap

func (e *ErrClient) Unwrap() error

Unwrap unwraps the actual error

type ErrorCode

type ErrorCode int

type Errors

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

func NewErrors

func NewErrors() Errors

func (*Errors) Register deprecated

func (e *Errors) Register(c ErrorCode, typ any)

Deprecated: Use RegisterError instead for type-safe operations

type JSONRPCError

type JSONRPCError struct {
	Code    ErrorCode      `json:"code"`
	Message string         `json:"message"`
	Meta    jsontext.Value `json:"meta,omitzero"`
	Data    any            `json:"data,omitzero"`
}

func (*JSONRPCError) Error

func (e *JSONRPCError) Error() string

func (*JSONRPCError) Unwrap

func (e *JSONRPCError) Unwrap() error

type LimitedReader

type LimitedReader struct {
	R io.Reader // underlying reader
	N int64     // max bytes remaining
}

func (*LimitedReader) Read

func (l *LimitedReader) Read(p []byte) (n int, err error)

type MarshalerFunc

type MarshalerFunc[T any] = func(*jsontext.Encoder, T) error

type MethodNameFormatter

type MethodNameFormatter func(namespace, method string) string

MethodNameFormatter is a function that takes a namespace and a method name and returns the full method name, sent via JSON-RPC. This is useful if you want to customize the default behaviour, e.g. send without the namespace or make it lowercase.

func NewMethodNameFormatter

func NewMethodNameFormatter(includeNamespace bool, nameCase CaseStyle) MethodNameFormatter

NewMethodNameFormatter creates a new method name formatter based on the provided options.

type Object

type Object[T any] struct {
	Value T `json:",embed"`
}

Object is my solution for named params in golang. Use an Object[T] type as the only param (except for context) in method, then its corresponded json object will be for "params" field in rpc call. T must be a Go struct, jsontext.Value, map[~string]T, or an unnamed pointer to such types. You can use Object[jsontext.Value] to get the usage similar to the old RawParams type.

func GetObject

func GetObject[T any](v T) Object[T]

type Option

type Option func(c *Config)

type Optional

type Optional[T any] *T

type RPCConnectionError

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

func (*RPCConnectionError) Error

func (e *RPCConnectionError) Error() string

func (*RPCConnectionError) Unwrap

func (e *RPCConnectionError) Unwrap() error

type RPCErrorCodec

type RPCErrorCodec interface {
	FromJSONRPCError(JSONRPCError) error
	ToJSONRPCError() (JSONRPCError, error)
}

type RPCServer

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

RPCServer provides a jsonrpc 2.0 http server handler

func NewServer

func NewServer(opts ...ServerOption) *RPCServer

NewServer creates new RPCServer instance

func (*RPCServer) AliasMethod

func (s *RPCServer) AliasMethod(alias, original string)

func (RPCServer) GetJsonOptions

func (h RPCServer) GetJsonOptions() json.Options

func (*RPCServer) GetLogger

func (s *RPCServer) GetLogger() *slog.Logger

func (*RPCServer) HandleRequest

func (s *RPCServer) HandleRequest(ctx context.Context, r io.Reader, w io.Writer)

func (*RPCServer) Register

func (s *RPCServer) Register(namespace string, handler any)

Register registers new RPC handler

Handler is any value with methods defined

func (*RPCServer) ServeHTTP

func (s *RPCServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

TODO: return errors to clients per spec

type ServerConfig

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

func (*ServerConfig) GetJsonOptions

func (c *ServerConfig) GetJsonOptions() json.Options

func (*ServerConfig) GetLogger

func (c *ServerConfig) GetLogger() *slog.Logger

type ServerOption

type ServerOption func(c *ServerConfig)

func WithMaxRequestSize

func WithMaxRequestSize(max int64) ServerOption

func WithReverseClient

func WithReverseClient[RP any](namespace string) ServerOption

WithReverseClient will allow extracting reverse client on **WEBSOCKET** calls. RP is a proxy-struct type, much like the one passed to NewClient.

func WithServerErrors

func WithServerErrors(es Errors) ServerOption

func WithServerJsonOptions

func WithServerJsonOptions(opts ...json.Options) ServerOption

func WithServerLogger

func WithServerLogger(logger *slog.Logger) ServerOption

func WithServerMethodNameFormatter

func WithServerMethodNameFormatter(formatter MethodNameFormatter) ServerOption

func WithServerPingInterval

func WithServerPingInterval(d time.Duration) ServerOption

func WithServerTimeout

func WithServerTimeout(d time.Duration) ServerOption

func WithTracer

func WithTracer(l Tracer) ServerOption

WithTracer allows the instantiator to trace the method calls and results. This is useful for debugging a client-server interaction.

type Tracer

type Tracer struct {
	OnParseError     TracerBytesFunc
	OnInvalidRequest TracerBytesFunc
	OnInvalidMethod  TracerRequestFunc
	OnInvalidParams  TracerRequestFunc
	OnRequestError   TracerParamsFunc
	OnResponseError  TracerParamsFunc
	OnNotification   TracerParamsFunc
	OnSuccess        TracerParamsFunc
}

type TracerBytesFunc

type TracerBytesFunc = func(data []byte, err error)

type TracerParamsFunc

type TracerParamsFunc = func(method string, params []reflect.Value, results []reflect.Value, err error)

type TracerRequestFunc

type TracerRequestFunc = func(jsonrpc string, id any, method string, params jsontext.Value, meta map[string]string, err error)

type UnmarshalerFunc

type UnmarshalerFunc[T any] = func(*jsontext.Decoder, T) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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