The use of google's grpc in golang

Keywords: Go Google github Netty

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.

Posted by IlikeTheWeb on Sun, 14 Apr 2019 20:15:33 -0700