Giter Site home page Giter Site logo

tinyrpc's Introduction

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

you can also use

> protoc --tinyrpc_out=gen-cli=true:. arith.proto --go_out=. arith.proto

to generate arith.cli.go, this file make it easier to call the server.

the code of arith.svr.go is shown below:

// 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 to define our services.

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

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 with three supported formats 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

tinyrpc's People

Contributors

gopower avatar hdheid avatar kingson4wu avatar wangqiim avatar wanzste avatar zehuamama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyrpc's Issues

Optimize tinyrpc performance

The header of tinyrpc uses protobuf encoding, but because reflection will affect its performance, consider using the standard library binary to encode and decode the header

For more details, see branch unstable

插件的使用

可以说明下,关于Service的代码生成可以使用官方自带的插件protoc --go_out=plugins=grpc:. arith.proto

Are there data races in serverCodec & clientCodec?

tinyrpc/codec/server.go

Lines 19 to 29 in 855d7a9

type serverCodec struct {
r io.Reader
w io.Writer
c io.Closer
request header.RequestHeader
serializer serializer.Serializer
mutex sync.Mutex // protects seq, pending
seq uint64
pending map[uint64]uint64
}

ReadRequestHeader,ReadRequestBody, WriteResponse can these functions be executed concurrently?
Why just lock "protects seq, pending",There may be data races about s.request and s.serializer.
Looks like client.go have the same problem.

error,please help me

I am a beginner of golang language,with the previous steps have been successfully executed, there is a error occur when i execute the command :"protoc --tinyrpc_out=. arith.proto --go_out=. arith.proto",
and the error is :
"protoc-gen-tinyrpc: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--tinyrpc_out: protoc-gen-tinyrpc: Plugin failed with status code 1."

what should i do to fix it? thanks a lot

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.