tinyrpc

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2022 License: BSD-2-Clause Imports: 6 Imported by: 0

README

tinyrpc

Go Report Card GitHub top language GitHub CodeFactor codecov  go_version

tinyrpc is a high-performance RPC framework based on protocol buffer encoding. It is based on net/rpc and supports multiple compression formats (gzip, snappy, zlib).

Language  English

Install

go install github.com/golang/protobuf/protoc-gen-go
go install github.com/zehuamama/tinyrpc/protoc-gen-tinyrpc

Quick Start

Fisrt, create a demo and import the tinyrpc package:

> go mod init demo
> go get github.com/zehuamama/tinyrpc

under the path of the project, create a protobuf file arith.proto:

syntax = "proto3";

package message;
option go_package="/message";

// ArithService Defining Computational Digital Services
service ArithService {
  // Add addition
  rpc Add(ArithRequest) returns (ArithResponse);
  // Sub subtraction
  rpc Sub(ArithRequest) returns (ArithResponse);
  // Mul multiplication
  rpc Mul(ArithRequest) returns (ArithResponse);
  // Div division
  rpc Div(ArithRequest) returns (ArithResponse);
}

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

message ArithResponse {
  int32 c = 1;
}

an arithmetic operation service is defined here, using protoc to generate code:

> protoc --tinyrpc_out=. arith.proto --go_out=. arith.proto

at this time, two files will be generated in the directory message: arith.pb.go and arith.svr.go

the code of arith.svr.go is as follows:

// Code generated by protoc-gen-tinyrpc.

package message

// ArithService Defining Computational Digital Services
type ArithService struct{}

// Add addition
func (this *ArithService) Add(args *ArithRequest, reply *ArithResponse) error {
	// define your service ...
	return nil
}

// Sub subtraction
func (this *ArithService) Sub(args *ArithRequest, reply *ArithResponse) error {
	// define your service ...
	return nil
}

// Mul multiplication
func (this *ArithService) Mul(args *ArithRequest, reply *ArithResponse) error {
	// define your service ...
	return nil
}

// Div division
func (this *ArithService) Div(args *ArithRequest, reply *ArithResponse) error {
	// define your service ...
	return nil
}

we need define our services.

Finally, under the path of the project, we create a file named main.go, the code is as follows:

package main

import (
	"demo/message"
	"log"
	"net"

	"github.com/zehuamama/tinyrpc"
)

func main() {
	lis, err := net.Listen("tcp", ":8082")
	if err != nil {
		log.Fatal(err)
	}

	server := tinyrpc.NewServer()
	server.RegisterName("ArithService", new(message.ArithService))
	server.Serve(lis)
}

a tinyrpc server is completed.

Client

We can create a tinyrpc client and call it synchronously with the Add function:

import (
        "demo/message"
	"github.com/zehuamama/tinyrpc"
...

conn, err := net.Dial("tcp", ":8082")
if err != nil {
	log.Fatal(err)
}
defer conn.Close()
client := tinyrpc.NewClient(conn)
resq := message.ArithRequest{A: 20, B: 5}
resp := message.ArithResponse{}
err = client.Call("ArithService.Add", &resq, &resp)
log.Printf("Arith.Add(%v, %v): %v ,Error: %v", resq.A, resq.B, resp.C, err)

you can also call asynchronously, which will return a channel of type *rpc.Call:


result := client.AsyncCall("ArithService.Add", &resq, &resp)
select {
case call := <-result:
	log.Printf("Arith.Add(%v, %v): %v ,Error: %v", resq.A, resq.B, resp.C, call.Error)
case <-time.After(100 * time.Microsecond):
	log.Fatal("time out")
}

of course, you can also compress the encoding, tinyrpc currently supports gzip, snappy, zlib:

import "github.com/zehuamama/tinyrpc/compressor"

...
client := tinyrpc.NewClient(conn, tinyrpc.WithCompress(compressor.Gzip))

Custom Serializer

If you want to customize the serializer, you must implement the Serializer interface:

type Serializer interface {
	Marshal(message interface{}) ([]byte, error)
	Unmarshal(data []byte, message interface{}) error
}

JsonSerializer is a serializer based Json:

type JsonSerializer struct{}

func (_ JsonSerializer) Marshal(message interface{}) ([]byte, error) {
	return json.Marshal(message)
}

func (_ JsonSerializer) Unmarshal(data []byte, message interface{}) error {
	return json.Unmarshal(data, message)
}

moving on, we create a HelloService with the following code:

type HelloRequest struct {
	Req string `json:"req"`
}

type HelloResponce struct {
	Resp string `json:"resp"`
}

type HelloService struct{}

func (_ *HelloService) SayHello(args *HelloRequest, reply *HelloResponce) error {
	reply.Resp = args.Req
	return nil
}

finally, we need to set the serializer on the rpc server:

func main() {
	lis, err := net.Listen("tcp", ":8082")
	if err != nil {
		log.Fatal(err)
	}

	server := tinyrpc.NewServer(tinyrpc.WithSerializer(JsonSerializer{}))
	server.Register(new(HelloService))
	server.Serve(lis)
}

a rpc server based on json serializer is completed.

Remember that when the rpc client calls the service, it also needs to set the serializer:

tinyrpc.NewClient(conn,tinyrpc.WithSerializer(JsonSerializer{}))

Contributing

If you are intersted in contributing to tinyrpc, please see here: CONTRIBUTING

License

tinyrpc is licensed under the term of the BSD 2-Clause License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	*rpc.Client
}

Client rpc client based on net/rpc implementation

func NewClient

func NewClient(conn io.ReadWriteCloser, opts ...Option) *Client

NewClient Create a new rpc client

func (*Client) AsyncCall

func (c *Client) AsyncCall(serviceMethod string, args interface{}, reply interface{}) chan *rpc.Call

AsyncCall asynchronously calls the rpc function and returns a channel of *rpc.Call

func (*Client) Call

func (c *Client) Call(serviceMethod string, args interface{}, reply interface{}) error

Call synchronously calls the rpc function

type Option

type Option func(o *options)

Option provides options for rpc

func WithCompress

func WithCompress(c compressor.CompressType) Option

WithCompress set client compression format

func WithSerializer added in v0.3.0

func WithSerializer(serializer serializer.Serializer) Option

WithSerializer set client serializer

type Server

type Server struct {
	*rpc.Server
	serializer.Serializer
}

Server rpc server based on net/rpc implementation

func NewServer

func NewServer(opts ...Option) *Server

NewServer Create a new rpc server

func (*Server) Register

func (s *Server) Register(rcvr interface{}) error

Register register rpc function

func (*Server) RegisterName

func (s *Server) RegisterName(name string, rcvr interface{}) error

RegisterName register the rpc function with the specified name

func (*Server) Serve

func (s *Server) Serve(lis net.Listener)

Serve start service

Directories

Path Synopsis
test.data

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL