Easy to use and developer friendly RPC library
- 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...
# install rpcx v2
go get -u github.com/gen-iot/rpcx/v2@latest
// import
import "github.com/gen-iot/rpcx/v2"
- Developer friendly
- Middlewares: dump,mq_proxy,recover,validate...
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 |
Remember :param ctx
,err
always required
- Both have
in
&out
func Function(ctx rpcx.Context, in InType)(out OutType, err error)
- Only
err
func Function(ctx rpcx.Context)(err error)
out
anderr
func Function(ctx rpcx.Context) (out OutType,err error)
in
anderr
func Function(ctx rpcx.Context, in InType)(err error)
core, err := rpcx.New()
err := core.Close()
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
})
sockAddr, err := liblpc.ResolveTcpAddr("127.0.0.1")
std.AssertError(err,"resolve addr")
callable := rpcx.NewClientStreamCallable(core, sockAddr, nil)
callable.Start()
// `fd` must be a valid file descriptor
callable := rpcx.NewConnStreamCallable(core,fd, nil)
callable.Start()
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)
All Call[0-6] support Timeout And Middlewares
Function | Header | In | Out |
---|---|---|---|
Call | |||
Call0 | ✅ | ||
Call1 | ✅ | ||
Call2 | ✅ | ✅ | |
Call3 | ✅ | ||
Call4 | ✅ | ✅ | |
Call5 | ✅ | ✅ | |
Call6 | ✅ | ✅ | ✅ |
middlewares works like AOP concept
as we know in Java
.
📌Import middlewares before use
import "github.com/gen-iot/rpcx/v2/middleware"
📌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)),
)
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
)
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)
try examples
Released under the MIT License