Erpc
An efficient, extensible and easy-to-use RPC framework.
Install / Use
/learn @andeya/ErpcREADME
eRPC
eRPC is an efficient, extensible and easy-to-use RPC framework.
Suitable for RPC, Microservice, Peer-to-Peer, IM, Game and other fields.

Install
-
go vesion ≥ 1.18
-
install
GO111MODULE=on go get -u -v -insecure github.com/andeya/erpc/v7
- import
import "github.com/andeya/erpc/v7"
Feature
- Use peer to provide the same API package for the server and client
- Provide multi-layout abstractions such as:
- peer
- session/socket
- router
- handle/context
- message
- protocol
- codec
- transfer filter
- plugin
- Support reboot and shutdown gracefully
- HTTP-compatible message format:
- Composed of two parts, the
Headerand theBody Headercontains metadata in the same format as HTTP headerBodysupports for custom codec of Content Type-Like, already implemented:- Protobuf
- Thrift
- JSON
- XML
- Form
- Plain
- Support push, call-reply and more message types
- Composed of two parts, the
- Support custom message protocol, and provide some common implementations:
rawproto- Default high performance binary protocoljsonproto- JSON message protocolpbproto- Ptotobuf message protocolthriftproto- Thrift message protocolhttproto- HTTP message protocol
- Optimized high performance transport layer
- Use Non-block socket and I/O multiplexing technology
- Support setting the size of socket I/O buffer
- Support setting the size of the reading message (if exceed disconnect it)
- Support controling the connection file descriptor
- Support a variety of network types:
tcptcp4tcp6unixunixpacketkcpquic- other
- websocket
- evio
- Provide a rich plug-in point, and already implemented:
- auth
- binder
- heartbeat
- ignorecase(service method)
- overloader
- proxy(for unknown service method)
- secure
- Powerful and flexible logging system:
- Detailed log information, support print input and output details
- Support setting slow operation alarm threshold
- Support for custom implementation log component
- Client session support automatically redials after disconnection
Benchmark
Self Test
-
A server and a client process, running on the same machine
-
CPU: Intel Xeon E312xx (Sandy Bridge) 16 cores 2.53GHz
-
Memory: 16G
-
OS: Linux 2.6.32-696.16.1.el6.centos.plus.x86_64, CentOS 6.4
-
Go: 1.9.2
-
Message size: 581 bytes
-
Message codec: protobuf
-
Sent total 1000000 messages
-
erpc
| client concurrency | mean(ms) | median(ms) | max(ms) | min(ms) | throughput(TPS) | | ------------------ | -------- | ---------- | ------- | ------- | --------------- | | 100 | 1 | 0 | 16 | 0 | 75505 | | 500 | 9 | 11 | 97 | 0 | 52192 | | 1000 | 19 | 24 | 187 | 0 | 50040 | | 2000 | 39 | 54 | 409 | 0 | 42551 | | 5000 | 96 | 128 | 1148 | 0 | 46367 |
- erpc/socket
| client concurrency | mean(ms) | median(ms) | max(ms) | min(ms) | throughput(TPS) | | ------------------ | -------- | ---------- | ------- | ------- | --------------- | | 100 | 0 | 0 | 14 | 0 | 225682 | | 500 | 2 | 1 | 24 | 0 | 212630 | | 1000 | 4 | 3 | 51 | 0 | 180733 | | 2000 | 8 | 6 | 64 | 0 | 183351 | | 5000 | 21 | 18 | 651 | 0 | 133886 |
Comparison Test
<table> <tr><th>Environment</th><th>Throughputs</th><th>Mean Latency</th><th>P99 Latency</th></tr> <tr> <td width="10%"><img src="https://github.com/andeya/rpc-benchmark/raw/master/result/env.png"></td> <td width="30%"><img src="https://github.com/andeya/rpc-benchmark/raw/master/result/throughput.png"></td> <td width="30%"><img src="https://github.com/andeya/rpc-benchmark/raw/master/result/mean_latency.png"></td> <td width="30%"><img src="https://github.com/andeya/rpc-benchmark/raw/master/result/p99_latency.png"></td> </tr> </table>- Profile torch of erpc/socket

- Heap torch of erpc/socket

Example
server.go
package main
import (
"fmt"
"time"
"github.com/andeya/erpc/v7"
)
func main() {
defer erpc.FlushLogger()
// graceful
go erpc.GraceSignal()
// server peer
srv := erpc.NewPeer(erpc.PeerConfig{
CountTime: true,
ListenPort: 9090,
PrintDetail: true,
})
// srv.SetTLSConfig(erpc.GenerateTLSConfigForServer())
// router
srv.RouteCall(new(Math))
// broadcast per 5s
go func() {
for {
time.Sleep(time.Second * 5)
srv.RangeSession(func(sess erpc.Session) bool {
sess.Push(
"/push/status",
fmt.Sprintf("this is a broadcast, server time: %v", time.Now()),
)
return true
})
}
}()
// listen and serve
srv.ListenAndServe()
}
// Math handler
type Math struct {
erpc.CallCtx
}
// Add handles addition request
func (m *Math) Add(arg *[]int) (int, *erpc.Status) {
// test meta
erpc.Infof("author: %s", m.PeekMeta("author"))
// add
var r int
for _, a := range *arg {
r += a
}
// response
return r, nil
}
client.go
package main
import (
"time"
"github.com/andeya/erpc/v7"
)
func main() {
defer erpc.SetLoggerLevel("ERROR")()
cli := erpc.NewPeer(erpc.PeerConfig{})
defer cli.Close()
// cli.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
cli.RoutePush(new(Push))
sess, stat := cli.Dial(":9090")
if !stat.OK() {
erpc.Fatalf("%v", stat)
}
var result int
stat = sess.Call("/math/add",
[]int{1, 2, 3, 4, 5},
&result,
erpc.WithAddMeta("author", "andeya"),
).Status()
if !stat.OK() {
erpc.Fatalf("%v", stat)
}
erpc.Printf("result: %d", result)
erpc.Printf("Wait 10 seconds to receive the push...")
time.Sleep(time.Second * 10)
}
// Push push handler
type Push struct {
erpc.PushCtx
}
// Push handles '/push/status' message
func (p *Push) Status(arg *string) *erpc.Status {
erpc.Printf("%s", *arg)
return nil
}
Usage
NOTE:
- It is best to set the packet size when reading:
SetReadLimit - The default packet size limit when reading is 1 GB
Peer(server or client) Demo
// Start a server
var peer1 = erpc.NewPeer(erpc.PeerConfig{
ListenPort: 9090, // for server role
})
peer1.Listen()
...
// Start a client
var peer2 = erpc.NewPeer(erpc.PeerConfig{})
var sess, err = peer2.Dial("127.0.0.1:8080")
Call-Struct API template
type Aaa struct {
erpc.CallCtx
}
func (x *Aaa) XxZz(arg *<T>) (<T>, *erpc.Status) {
...
return r, nil
}
- register it to root router:
// register the call route
// HTTP mapping: /aaa/xx_zz
// RPC mapping: Aaa.XxZz
peer.RouteCall(new(Aaa))
// or register the call route
// HTTP mapping: /xx_zz
// RPC mapping: XxZz
peer.RouteCallFunc((*Aaa).XxZz)
Service method mapping
-
The default mapping(HTTPServiceMethodMapper) of struct(func) name to service methods:
AaBb->/aa_bbABcXYz->/abc_xyzAa__Bb->/aa_bbaa__bb->/aa_bbABC__XYZ->/abc_xyzAa_Bb->/aa/bbaa_bb->/aa/bbABC_XYZ->/abc/xyz
erpc.SetServiceMethodMapper(erpc.HTTPServiceMethodMapper) -
The mapping(RPCServiceMethodMapper) of struct(func) name to service methods:
AaBb->AaBbABcXYz->ABcXYzAa__Bb->Aa_Bbaa__bb->aa_bbABC__XYZ->ABC_XYZAa_Bb->Aa.Bbaa_bb->aa.bbABC_XYZ->ABC.XYZ
erpc.SetServiceMethodMapper(erpc.RPCServiceMethodMapper)
Call-Function API template
func XxZz(ctx erpc.CallCtx, arg *<T>) (<T>, *erpc.Status) {
...
return r, nil
}
- register it to root router:
// register the call route
// HTTP mapping: /xx_zz
// RPC mapping: XxZz
peer.RouteCallFunc(XxZz)
Push-Struct API template
type Bbb struct {
erpc.PushCtx
}
func (b *Bbb) YyZz(arg *<T>) *erpc.Status {
...
return nil
}
- register it to root router:
// register the push handler
// HTTP mapping: /bbb/yy_zz
// RPC mapping: Bbb.YyZz
peer.RoutePush(new(Bbb))
// or register the push handler
// HTTP mapping: /yy_zz
// RPC mapping: YyZz
peer.RoutePushFunc((*Bbb).YyZz)
Push-Function API template
// YyZz register the handler
func YyZz(ctx erpc.PushCtx, arg *<T>) *erpc.Status {
...
return nil
}
- register it to root router:
// register the push handler
// HTTP
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
