rmb

package module
v0.15.1 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 11 Imported by: 4

README

Go Documentation

Introduction

This is a GO sdk that can be used to build both services, and clients that can talk over the rmb.

RMB is a message bus that enable secure and reliable RPC calls across the globe.

RMB itself does not implement an RPC protocol, but just the secure and reliable messaging hence it's up to server and client to implement their own data format.

How it works

If two processes needed to communicate over RMB, they both need to have some sort of a connection to an rmb-relay.
This connection could be established using a direct-client, or an rmb-peer.

Direct client

A process could connect to an rmb-relay using a direct client.
To create a new direct client instance, a process needs to have:

  • A valid mnemonics, with an activated account on the TFChain.
  • The key type of these mnemonics.
  • A relay URL that the direct client will connect to.
  • A session id. This could be anything, but a twin must only have a unique session id per connection.
  • A substrate connection.
Example

Creating a new direct client instance:

subManager := substrate.NewManager("wss://tfchain.dev.grid.tf/ws")
sub, err := subManager.Substrate()
if err != nil {
    return fmt.Errorf("failed to connect to substrate: %w", err)
}

defer sub.Close()
client, err := direct.NewRpcClient(direct.KeyTypeSr25519, mnemonics, "wss://relay.dev.grid.tf", "test-client", sub, false)
if err != nil {
    return fmt.Errorf("failed to create direct client: %w", err)
}

Assuming there is a remote calculator process that could add two integers, an rmb call using the direct client would look like this:

x := 1
y := 2
var sum int
err := client.Call(ctx, destinationTwinID, "calculator.add", []int{x, y}, &sum)

Documentation

Index

Constants

View Source
const (
	DefaultSchema = "application/json"

	// DefaultAddress default redis address when no address is passed
	DefaultAddress = "tcp://127.0.0.1:6379"
)

Variables

View Source
var (
	// ErrFunctionNotFound is an err returned if the handler function is not found
	ErrFunctionNotFound = fmt.Errorf("function not found")
)

Functions

func GetTwinID

func GetTwinID(ctx context.Context) uint32

GetTwinID returns the twin id from context.

func LoggerMiddleware

func LoggerMiddleware(ctx context.Context, payload []byte) (context.Context, error)

LoggerMiddleware simple logger middleware.

func NewRedisPool added in v0.14.4

func NewRedisPool(address string, size ...uint32) (*redis.Pool, error)

Types

type Client

type Client interface {
	Call(ctx context.Context, twin uint32, fn string, data interface{}, result interface{}) error
}

Client is an rmb abstract client interface.

func Default

func Default() (Client, error)

Default return instance of to default (local) rmb shortcut for NewClient(DefaultAddress)

func NewRMBClient

func NewRMBClient(address string, poolSize ...uint32) (Client, error)

NewRMBClient creates a new rmb client that runs behind an rmb-peer. This client does not talk to the rmb relay directly, instead talk to an rmb-peer instance (like a gateway) that itself maintains a connection to the relay. the rmb-peer does all the heavy lifting, including signing, encryption, validation of the response, etc...

hence the address in this case, is an address to the local redis that must be the same one used with the rmb-peer process.

for more details about rmb-peer please check https://github.com/threefoldtech/rmb-rs Since the rmb protocol does not specify a "payload" format this Client and the DefaultRouter both uses json to encode and decode the rpc body. Hence this client should be always 100% compatible with services built with the DefaultRouter.

type DefaultRouter

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

DefaultRouter implements Router interface. It then can be used to register handlers to quickly implement servers that are callable over RMB.

func NewRouter

func NewRouter(address string) (*DefaultRouter, error)

NewRouter creates a new default router. with the local redis address. Normally you want to do NewRouter(DefaultAddress)

func (*DefaultRouter) Handlers

func (m *DefaultRouter) Handlers() []string

Handlers return full name of all registered handlers

func (*DefaultRouter) Run

func (m *DefaultRouter) Run(ctx context.Context) error

Run runs listeners to the configured handlers and will trigger the handlers in the case an event comes in

func (*DefaultRouter) Subroute

func (m *DefaultRouter) Subroute(prefix string) Router

func (*DefaultRouter) Use

func (m *DefaultRouter) Use(mw Middleware)

func (*DefaultRouter) WithHandler

func (m *DefaultRouter) WithHandler(topic string, handler Handler)

WithHandler adds a topic handler to the messagebus

type Error

type Error struct {
	Code    uint32 `json:"code"`
	Message string `json:"message"`
}

type Handler

type Handler func(ctx context.Context, payload []byte) (interface{}, error)

Handler is a handler function type

type Incoming

type Incoming struct {
	Version    int    `json:"ver"`
	Reference  string `json:"ref"`
	Command    string `json:"cmd"`
	Expiration int    `json:"exp"`
	Data       string `json:"dat"`
	TwinSrc    string `json:"src"`
	RetQueue   string `json:"ret"`
	Schema     string `json:"shm"`
	Epoch      int64  `json:"now"`
}

Incoming request that need to be handled by servers

func GetRequest

func GetRequest(ctx context.Context) Incoming

GetRequest gets a message from the context, panics if it's not there

func (*Incoming) GetPayload

func (m *Incoming) GetPayload() ([]byte, error)

GetPayload returns the payload for a message's data

type IncomingResponse

type IncomingResponse struct {
	Version   int    `json:"ver"`
	Reference string `json:"ref"`
	Data      string `json:"dat"`
	TwinSrc   string `json:"src"`
	Schema    string `json:"shm"`
	Epoch     int64  `json:"now"`
	Error     *Error `json:"err,omitempty"`
}

type Middleware

type Middleware func(ctx context.Context, payload []byte) (context.Context, error)

Middleware is middleware function type

type OutgoingResponse

type OutgoingResponse struct {
	Version   int    `json:"ver"`
	Reference string `json:"ref"`
	Data      string `json:"dat"`
	TwinDest  string `json:"dst"`
	Schema    string `json:"shm"`
	Epoch     int64  `json:"now"`
	Error     *Error `json:"err,omitempty"`
}

type RemoteError

type RemoteError struct {
	Code    uint32
	Message string
}

func (RemoteError) Error

func (e RemoteError) Error() string

type Request

type Request struct {
	Version    int      `json:"ver"`
	Reference  string   `json:"ref"`
	Command    string   `json:"cmd"`
	Expiration int      `json:"exp"`
	Data       string   `json:"dat"`
	TwinDest   []uint32 `json:"dst"`
	Session    *string  `json:"con"`
	RetQueue   string   `json:"ret"`
	Schema     string   `json:"shm"`
	Epoch      int64    `json:"now"`
}

Request is an outgoing request struct used to make rpc calls over rmb

func (*Request) GetPayload

func (m *Request) GetPayload() ([]byte, error)

GetPayload returns the payload for a message's data

type Router

type Router interface {
	WithHandler(route string, handler Handler)
	Subroute(route string) Router
	Use(Middleware)
}

Router is the router interface

Directories

Path Synopsis
examples
Package direct package provides the functionality to create a direct websocket connection to rmb relays without the need to rmb peers.
Package direct package provides the functionality to create a direct websocket connection to rmb relays without the need to rmb peers.

Jump to

Keyboard shortcuts

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