Package rpc implements a remote procedure call over TCP, UNIX, HTTP and WS. The rpc improves throughput and reduces latency. Up to 4 times faster than net/rpc.
- More throughput and less latency.
- Netpoll epoll/kqueue/net
- Network tcp/unix/http/ws
- Codec json/code/pb
- Multiplexing/Pipelining
- Auto batching
- Call/Go/RoundTrip/Ping/Stream/CallWithContext
- Conn/Transport/Client
- TLS
Comparison to other packages
Package | netrpc | jsonrpc | rpc | grpc | rpcx |
---|---|---|---|---|---|
Epoll/Kqueue | No | No | Yes | No | No |
Multiplexing | Yes | Yes | Yes | Yes | Yes |
Pipelining | No | No | Yes | No | No |
Auto Batching | No | No | Yes | No | No |
Transport | No | No | Yes | No | No |
go get github.com/hslam/rpc
import "github.com/hslam/rpc"
arith.proto
syntax = "proto3";
package service;
message ArithRequest {
int32 a = 1;
int32 b = 2;
}
message ArithResponse {
int32 pro = 1;
}
protoc ./arith.proto --gogofaster_out=./
arith.go
package service
type Arith struct{}
func (a *Arith) Multiply(req *ArithRequest, res *ArithResponse) error {
res.Pro = req.A * req.B
return nil
}
server.go
package main
import (
"github.com/hslam/rpc"
"github.com/hslam/rpc/examples/codec/pb/service"
)
func main() {
rpc.Register(new(service.Arith))
rpc.Listen("tcp", ":9999", "pb")
}
conn.go
package main
import (
"fmt"
"github.com/hslam/rpc"
"github.com/hslam/rpc/examples/codec/pb/service"
)
func main() {
conn, err := rpc.Dial("tcp", ":9999", "pb")
if err != nil {
panic(err)
}
defer conn.Close()
req := &service.ArithRequest{A: 9, B: 2}
var res service.ArithResponse
if err = conn.Call("Arith.Multiply", req, &res); err != nil {
panic(err)
}
fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro)
}
transport.go
package main
import (
"fmt"
"github.com/hslam/rpc"
"github.com/hslam/rpc/examples/codec/pb/service"
)
func main() {
trans := &rpc.Transport{
MaxConnsPerHost: 1,
MaxIdleConnsPerHost: 1,
Options: &rpc.Options{Network: "tcp", Codec: "pb"},
}
defer trans.Close()
req := &service.ArithRequest{A: 9, B: 2}
var res service.ArithResponse
if err := trans.Call(":9999", "Arith.Multiply", req, &res); err != nil {
panic(err)
}
fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro)
}
client.go
package main
import (
"fmt"
"github.com/hslam/rpc"
"github.com/hslam/rpc/examples/codec/pb/service"
)
func main() {
opts := &rpc.Options{Network: "tcp", Codec: "pb"}
client := rpc.NewClient(opts, ":9997", ":9998", ":9999")
client.Scheduling = rpc.LeastTimeScheduling
defer client.Close()
req := &service.ArithRequest{A: 9, B: 2}
var res service.ArithResponse
if err := client.Call("Arith.Multiply", req, &res); err != nil {
panic(err)
}
fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro)
}
context.go
package main
import (
"context"
"fmt"
"github.com/hslam/rpc"
"github.com/hslam/rpc/examples/codec/pb/service"
"time"
)
func main() {
conn, err := rpc.Dial("tcp", ":9999", "pb")
if err != nil {
panic(err)
}
defer conn.Close()
req := &service.ArithRequest{A: 9, B: 2}
var res service.ArithResponse
emptyCtx := context.Background()
valueCtx := context.WithValue(emptyCtx, rpc.BufferContextKey, make([]byte, 64))
ctx, cancel := context.WithTimeout(valueCtx, time.Minute)
defer cancel()
err = conn.CallWithContext(ctx, "Arith.Multiply", req, &res)
if err != nil {
panic(err)
}
fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro)
}
9 * 2 = 18
This package is licensed under a MIT license (Copyright (c) 2019 Meng Huang)
rpc was written by Meng Huang.