This is a creation in Article, where the information may have evolved or changed.
Hello GRPC
As it is customary, from a Hello project, this project defines a Hello service, where the client sends a request containing the string name and the server returns a hello message.
Process:
Write a .proto description file
Compiling build .pb.go files
The service side implements the agreed interface and provides services
The client invokes the method request service by convention
Project directory:
$GOPATH/src/grpc-go-practice/example/|—— hello/ |—— client/ |—— main.go // 客户端 |—— server/ |—— main.go // 服务端|—— proto/ |—— hello.proto // proto描述文件 |—— hello.pb.go // proto编译后文件
Sample code
Description file: Proto/hello.proto
syntax = "proto3"; // 指定proto版本package proto; // 指定包名// 定义Hello服务service Hello { // 定义SayHello方法 rpc SayHello(HelloRequest) returns (HelloReply) {}}// HelloRequest 请求结构message HelloRequest { string name = 1;}// HelloReply 响应结构message HelloReply { string message = 1;}
A Hello service is defined in the Hello.proto file that contains a SayHello method that declares HelloRequest and HelloReply uses the message structure for requests and responses. The client uses HelloRequest the parameter invocation SayHello method to request the service side of the service-side response HelloReply message. Protobuf's syntax will be explained in detail later, so there's no need to dwell on it.
Compile the build .pb.go file:
# 编译hello.protoprotoc -I . --go_out=plugins=grpc:. ./hello.proto
The generated .pb.go file, as described .proto in the file, contains the server-side interface HelloServer description, Client interface and implementation HelloClient , and HelloRequest , HelloResponse struct, do not manually edit the file .
Implementing a server-side interface: Server/main.go
package mainimport ( "net" pb "go-grpc-practice/example/proto" // 引入编译生成的包 "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/grpclog")const ( // Address gRPC服务地址 Address = "127.0.0.1:50052")// 定义helloService并实现约定的接口type helloService struct{}// HelloService ...var HelloService = helloService{}func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { resp := new(pb.HelloReply) resp.Message = "Hello " + in.Name + "." return resp, nil}func main() { listen, err := net.Listen("tcp", Address) if err != nil { grpclog.Fatalf("failed to listen: %v", err) } // 实例化grpc Server s := grpc.NewServer() // 注册HelloService pb.RegisterHelloServer(s, HelloService) grpclog.Println("Listen on " + Address) s.Serve(listen)}
Run:
go run main.goListen on 50051 //服务端已开启并监听50051端口
The server introduces the compiled proto package, implements the agreed interface, and the interface description can view hello.pb.go the interface description in the file HelloServer . Instantiate GRPC server and register HelloService to start serving.
Client invocation: Client/main.go
package mainimport ( pb "go-grpc-practice/example/proto" // 引入proto包 "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/grpclog")const ( // Address gRPC服务地址 Address = "127.0.0.1:50052")func main() { // 连接 conn, err := grpc.Dial(Address, grpc.WithInsecure()) if err != nil { grpclog.Fatalln(err) } defer conn.Close() // 初始化客户端 c := pb.NewHelloClient(conn) // 调用方法 reqBody := new(pb.HelloRequest) reqBody.Name = "gRPC" r, err := c.SayHello(context.Background(), reqBody) if err != nil { grpclog.Fatalln(err) } grpclog.Println(r.Message)}
Run:
go run main.goHello gRPC // 接收到服务端响应
The client initiates the connection and invokes the declared method directly, initiating the request to the server and using the posture as if it were a local method. If you receive a "Hello Grpc" reply, congratulations on your use of GO-GRPC.
The following section describes the syntax of protobuf in detail and resolves the relationship between Protobuf Declaration and compiled Golang code in detail.
Reference
Sample code for this series