Prepare the environment

Install the Protobuf environment

See Golang for protobuf

Install the gRpc environment

go get google.golang.org/grpc
Copy the code

Write proto files

  • Directory format

syntax = "proto3";

package lightweight;

service Gym {
  rpc BodyBuilding (Person) returns (Reply){

  }
}

message Person{
  string name = 1;
  repeated string actions = 2;
}

message Reply {
  int32 code = 1;
  string msg = 2;
}
Copy the code

Compile the PROto file to generate the GO file

Go to the directory of the proto file

protoc --go_out=plugins=grpc:.. /lightweight/. gym.protoCopy the code

The generated go file is stored in the Lightweight directory gym.pb.go

Compiling into the raw GO file is key to several functions

This registration function requires the server to register the server after GRPC service is enabled, so we need to implement the interface of GymServer

func RegisterGymServer(s *grpc.Server, srv GymServer) {
	s.RegisterService(&_Gym_serviceDesc, srv)
}
Copy the code
  • GymServer interface: you need to implement it yourselfGymServerThis interface overrides the BodyBuilding method
// GymServer is the server API for Gym service.
type GymServer interface {
	BodyBuilding(context.Context, *Person) (*Reply, error)
}
Copy the code
  • The client

The GRPC service channel must be enabled on the client and must correspond to the same service port on the server

// GymClient is the client API for Gym service. type GymClient interface { BodyBuilding(ctx context.Context, in *Person, opts ... grpc.CallOption) (*Reply, error) } func NewGymClient(cc grpc.ClientConnInterface) GymClient { return &gymClient{cc} } func (c *gymClient) BodyBuilding(ctx context.Context, in *Person, opts ... grpc.CallOption) (*Reply, error) { out := new(Reply) err := c.cc.Invoke(ctx, "/lightweight.Gym/BodyBuilding", in, out, opts...) if err ! = nil { return nil, err } return out, nil }Copy the code

Write server side

package main import ( "context" "fmt" pb "github.com/example/grpc-demo/lightweight" "google.golang.org/grpc" "log" "net"  ) const ( port = ":50051" ) type Server struct { pb.UnimplementedGymServer } func (s *Server) BodyBuilding(ctx Context.Context, person * pb.person) (* pb.reply, error) {FMT.Printf("%s is working out, action: %s \n", person.Name, person.Actions) return &pb.Reply{Code: 0, Msg: "ok"}, nil } func main() { lis, err := net.Listen("tcp", port) if err ! = nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGymServer(s, &Server{}) if err := s.Serve(lis); err ! = nil { log.Fatalf("failed to serve: %v", err) } }Copy the code

Writing a client

package main import ( "context" "fmt" pb "github.com/example/grpc-demo/lightweight" "google.golang.org/grpc" "log" "time" ) const ( address = "localhost:50051" ) func main() { conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err ! = nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGymClient(conn) ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second) defer cancelFunc() r, err := c.BodyBuilding(ctx, &pb.Person{ Name: "daxiongdi", Actions: []string{" err ", "hard pull "," squats "},}) if err! = nil { log.Fatalf("error: %v", err) } fmt.Printf("code: %d, msg: %s", r.Code, r.Msg) }Copy the code

Start, run

// Start the server go run gym_server.go // Start the client go run gym_client.goCopy the code

print

Daxiongdi is working out, doing: [Bench press hard pull squat]Copy the code

Note:

This project uses go Moudle, which is prefixed with github.com/example/grpc-demo when packages are introduced into the project

go init mod github.com/example/grpc-demo
go tidy
go mod vendor
Copy the code

Reference:

GRPC official document Chinese version

Go version

go-grpc-middleware

GRPC detailed introduction tutorial

GRPC detailed introduction tutorial, Golang/Python/PHP multi-language explanation