Skip to content
/ rpc Public

Package rpc implements a remote procedure call over TCP, UNIX, HTTP and WS. Up to 4x faster than net/rpc.

License

Notifications You must be signed in to change notification settings

hslam/rpc

Repository files navigation

rpc

PkgGoDev Build Status codecov Go Report Card LICENSE

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.

Feature

  • 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
Low Concurrency

rpcrpc

High Concurrency

rpcrpc

Get started

Install

go get github.com/hslam/rpc

Import

import "github.com/hslam/rpc"

Usage

arith.proto

syntax = "proto3";
package service;

message ArithRequest {
    int32 a = 1;
    int32 b = 2;
}

message ArithResponse {
    int32 pro = 1;
}

GoGo Protobuf

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)
}

Output

9 * 2 = 18

License

This package is licensed under a MIT license (Copyright (c) 2019 Meng Huang)

Author

rpc was written by Meng Huang.