Getting started with gRPC

Keywords: Go Back-end

grpc framework

reference material:

GRPC is a cross language, high-performance and general open source RPC framework developed by Google based on Protobuf. GRPC is designed based on HTTP/2 protocol and can provide multiple services based on one HTTP/2 link, which is more friendly to mobile devices.

In gRPC, the client application can directly call the methods of the server application on another different machine like calling the local object, making it easier for you to create distributed applications and services. Like many RPC systems, gRPC is based on the following concepts:

  • Define a service and specify its methods (including parameters and return types) that can be called remotely.
  • Implement this interface on the server side and run a gRPC server to handle client calls.

Originally, I learned from the video on station b, but I found that most of them had various problems due to the version when following the actual combat, so I opened the official website, followed the official website, and learned with reference to the video and Baidu materials.
After a brief introduction, let's start the actual combat together!

1 prerequisites

You can install using the following two commands

go install google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc

Configure environment variables

export PATH="$PATH:$(go env GOPATH)/bin"

After configuration, the environment is OK. At this time, there will be the following two files in the gopath/bin directory

2 actual combat links

In this grpc practice project, the goal is to realize a function. The client can call the server and the functions of the server. After the server receives the message, it returns a response to the client.
Create a new project directory with the following structure:
grpcPrac
├── client
│ └── client.go
├── message
│ └── message.proto
└── server
└── server.go

2.1 proto file creation

message Used to write.proto Format file, server Directory server code, client Directory to write client code.
First in message Create under folder directory message.proto File, write as follows
syntax = "proto3";

option go_package = ".;message";

message MessageResponse {
 string responseSomething = 1;
}

message MessageRequest {
 string saySomething = 1;
}

service MessageSender {
 rpc Send(MessageRequest) returns (MessageResponse) {}
}

option go_package = ".;message" here is the package after compilation.

As can be seen from the proto file, we have defined a service called MessageSender, which has an rpc method called Send. This method will Send a MessageRequest and then return a MessageResponse.

Execute the following command in the message folder Directory:

protoc --go_out=. message.proto
protoc --go-grpc_out=. message.proto

At this time, the message.proto file will be translated into two. go files, as follows:

In some online tutorials, there are such generation methods:

protoc --go_out=plugins=grpc:. helloworld.proto

This generation method uses the github version of protocol Gen go, and the project has been taken over by Google.

Moreover, if this generation method is used, the XXX in the above figure will not be generated_ Grpc.pb.go and xxx.pb.go only generate xxx.pb.go files.

In addition, you may encounter this error:
protoc-gen-go-grpc: 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 --go-grpc_out: protoc-gen-go-grpc: Plugin failed with status code 1.
This is because you have not installed the plug-in protocol Gen go grpc. This problem should not appear in this article.

You may also encounter this problem:

--go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC

This is because you installed a newer version of protocol Gen go, but you used the older version of the build command.

2.2 server code

Create a server.go file in the server folder,

package main

import (
	"context"
	"google.golang.org/grpc"
	msg "grpcPrac/message"
	"log"
	"net"
)

const (
	address = "localhost:12345"
)

type server struct {
	msg.UnimplementedMessageSenderServer
}

//Implement the Send method of the message interface
func (this *server)Send(ctx context.Context,in *msg.MessageRequest) (*msg.MessageResponse, error) {
	log.Printf("Received: %v", in.GetSaySomething())
	return &msg.MessageResponse{ResponseSomething: "Hello " + in.GetSaySomething()},nil
}

func main() {
	//Set listening port
	lis, err := net.Listen("tcp", address)
	if err!= nil{
		log.Fatalf("Fail to listen:%v", err)
	}
	// Get grpc server object
	srv := grpc.NewServer()
 	
 	//Register grpc service
	msg.RegisterMessageSenderServer(srv, &server{})
	log.Printf("server listening at %v\n",lis.Addr())
	
	//Provide grpc service on the specified port
	if err:= srv.Serve(lis);err!=nil{
		log.Fatalf("failed to serve:%v",err)
	}

}

2.3 client

Create a client.go file in the Client folder with the following code:

package main

import (
	"context"
	"google.golang.org/grpc"
	msg "grpcPrac/message"
	"log"
	"time"
)

const (
	address = "localhost:12345"
	defaultName = "world"
)
func main() {
	//Establish connection with grpc service
	conn, err := grpc.Dial(address,grpc.WithInsecure(),grpc.WithBlock())
	if err!= nil{
		log.Fatalf("Did not connect :%v\n",err)
	}
	defer conn.Close()
	c := msg.NewMessageSenderClient(conn)

	//contact the server
	name := defaultName
	ctx ,cancel := context.WithTimeout(context.Background(),time.Second)
	defer cancel()
	r, err := c.Send(ctx,&msg.MessageRequest{SaySomething: name})
	if err!= nil{
		log.Fatalf("Could not Send :%v\n",err)
	}
	log.Printf("Response : %s\n",r.GetResponseSomething())
}

Use the terminal to enter the server and client directories and run the code respectively. The effect is as follows

This shows that we successfully call the server function through the client.

last

One of the pits is worth recording. After the. proto file is translated into go, message_grpc.pb.go has one more line of code for forward compatibility
Therefore, when defining the structure on the server side, do not forget to add this line

Posted by deeem on Thu, 28 Oct 2021 12:35:39 -0700