Skip to content
/ rpcx Public

Easy to use and developer friendly RPC library

License

Notifications You must be signed in to change notification settings

gen-iot/rpcx

Repository files navigation

rpcx

Easy to use and developer friendly RPC library

go report license Maintenance PRs Welcome Ask Me Anything !

Difference Between Other RPC Libraries

  • Once Callable established, local and remote are both in Full duplex mode.
  • No more client or server roles, Callables can call/called each others
  • Lots of Middlewares and developer can Custom their own middleware!
  • It works without any proto files , just define functions as usual.
  • Based on asynchronous I/O (liblpc) and provides synchronous call semantics
  • High Performace: event drivend, msgpack(for serialize),reuse context,goroutine pool...

Usage

# install rpcx v2
go get -u github.com/gen-iot/rpcx/v2@latest
// import 
import "github.com/gen-iot/rpcx/v2"

Overview

  • Developer friendly
  • Middlewares: dump,mq_proxy,recover,validate...

Middlewares

Name Desciption
dump dump request/response content
mq_proxy transfer requst/response
over custom message queue
recover recover panic
validate validate request/response data
req_not_nill discard request which req param is nil

Getting Started

RPC Functions Formal

Remember :param ctx,err always required

  1. Both have in&out
func Function(ctx rpcx.Context, in InType)(out OutType, err error)
  1. Only err
func Function(ctx rpcx.Context)(err error)
  1. out and err
func Function(ctx rpcx.Context) (out OutType,err error)
  1. in and err
func Function(ctx rpcx.Context, in InType)(err error)

Create Core

core, err := rpcx.New()

Close Core

err := core.Close()

Register RPC Function

core, err := rpcx.New()
std.AssertError(err, "new rpc")
core.RegFuncWithName(
    "hello", // manual specified func name
    func(ctx rpcx.Context, msg string) (string, error) {
        return "hello from server", nil
    })

Connect To Remote Core

sockAddr, err := liblpc.ResolveTcpAddr("127.0.0.1")
std.AssertError(err,"resolve addr")
callable := rpcx.NewClientStreamCallable(core, sockAddr, nil)
callable.Start()

Add Exist Conn To Core

// `fd` must be a valid file descriptor
callable := rpcx.NewConnStreamCallable(core,fd, nil)
callable.Start()

Invoke RPC Functions

Suppose there is a remote function:

func hello(ctx rpcx.Context)(string,error)

Now call it

out := new(string)
err := callable.Call3(time.Second*5, "hello", out)
std.AssertError(err, "call 'hello'")
fmt.Println("result:",*out)

Callable Calls

All Call[0-6] support Timeout And Middlewares

Function Header In Out
Call
Call0
Call1
Call2
Call3
Call4
Call5
Call6

Middleware

middlewares works like AOP concept as we know in Java.

📌Import middlewares before use

import "github.com/gen-iot/rpcx/v2/middleware"

RPC Core

📌middlewares apply on rpc core will affect whole rpc context

core, err := rpcx.New()
std.AssertError(err, "new rpc core")
core.Use(
    middleware.Recover(true), // recover 
    middleware.ValidateStruct( // validator
        middleware.ValidateInOut,
        std.NewValidator(std.LANG_EN)),
)

RPC Functions

core, err := rpcx.New()
std.AssertError(err, "new rpc")
core.RegFuncWithName("hello",
    func(ctx rpcx.Context, msg string) (string, error) {
        return "hello from server", nil
    },
    middleware.LoginRequred(),  // require logined
    middleware.MustAdmin(),       // require admin role
)

Callable

simple call

err := callable.Call("hello",
    middleware.Recover(true), // recover 
)

simple call with headers

ackHeader, err := callable.Call1("helloWithHeader",&RpcMsgHeader{
                    "key1":"value1",
                    "key2":"value2",
                },
    middleware.Recover(true), // recover 
)
fmt.Println("ack header->",ackHeader)

More Example

try examples

License

Released under the MIT License