GRPC is a high-performance, cross-language RPC framework of google open source. It is based on HTTP2 protocol, protobuf 3.x and Netty 4.x.
I wrote a previous article on the use of the rpc package of the golang standard library, and this article goes on to talk about google's grpc.
introduce
In gRPC, client applications can directly call the method of server applications on another different machine just like local objects, which makes it easier for you to create distributed applications and services.
There are many advantages of using grpc. It supports many languages. Binary data can speed up the transmission. Multiplexing based on http2 can reduce the number of connections between services. It also improves the development efficiency in the same way as calling functions.
Grpc is available in go version. Here's how to use grpc in golang.
install
grpc supports versions 1.5 and above.
Install grpc-go with the following commands:
go get google.golang.org/grpc
Install Protocol Buffers v3
go https://github.com/google/protobuf/releases Download the latest stable version, decompress it, and put the files in $PATH.
Install plug-ins
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
Don't forget to add $GOPATH/bin to $PATH:
export PATH=$PATH:$GOPATH/bin
Example
Sample Code Gets Address: https://github.com/andyidea/go-example.
The code file structure is as follows
├── bin │ ├── grpc-client │ └── grpc-server └── src └── grpc-helloworld ├── greeter_client │ └── main.go ├── greeter_server │ └── main.go └── helloworld ├── helloworld.pb.go └── helloworld.proto
There are three packages in grpc-helloworld, greeter_client is client code, greeter_server is server code and HelloWorld is protocol file.
Look at the agreement first.
helloworld.proto
syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
The protocol defines two structures HelloRequest and HelloReply, and a function SayHello, whose parameter is HelloRequest, returns HelloReply.
Generate the go file of the protocol under src/with the following command:
protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
This generates the helloworld.pb.go protocol file.
Then let's look at the server-side code:
package main import ( "log" "net" "golang.org/x/net/context" "google.golang.org/grpc" pb "grpc-helloworld/helloworld" "google.golang.org/grpc/reflection" ) const ( port = ":50051" ) // server is used to implement helloworld.GreeterServer. type server struct{} // SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) // Register reflection service on gRPC server. reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
The main logic on the server side is to implement the SayHello method in the previous protocol, where the string Hello and parameters are stitched together and returned.
The go file generated by the protocol gives a RegisterGreeter Server method, which we use to bind the structure of the implementation function and the server.
Then the client code:
package main import ( "log" "os" "golang.org/x/net/context" "google.golang.org/grpc" pb "grpc-helloworld/helloworld" ) const ( address = "localhost:50051" defaultName = "world" ) func main() { // Set up a connection to the server. conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message) }
The idea of the client is also clear, establish an rpc client connection, bind the connection with pb.NewGreeterClient and protocol, return a client object, with which remote functions can be invoked.
The output of the call is as follows:
Greeting: Hello world
This concludes the example. Sample Code Gets Address: https://github.com/andyidea/go-example.