快速开始

本指南将带你通过一个简单的工作示例开始使用 Go 中的 gRPC。

前提条件

  • Go,Go 的最新两个主要版本之一。

    安装说明,请参见 Go 的 [入门指南](https://golang.org/doc/install)。

  • 协议缓冲区编译器 protoc版本 3

    安装说明,请参见 协议缓冲区编译器安装

  • Go 插件用于协议编译器:

    1. 使用以下命令安装 Go 的协议编译器插件:

      go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
      go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    2. 更新你的 PATH,以便 protoc 编译器能够找到这些插件:

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

获取示例代码

示例代码是 grpc-go 仓库的一部分。

  1. 你可以下载仓库的 zip 文件 并解压,或者克隆仓库:

    git clone -b v1.69.2 --depth 1 https://github.com/grpc/grpc-go
  2. 切换到快速入门示例目录:

    cd grpc-go/examples/helloworld

运行示例

examples/helloworld 目录:

  • 编译并执行服务器代码:

    go run greeter_server/main.go
  • 在另一个终端,编译并执行客户端代码,以查看客户端输出:

    go run greeter_client/main.go
    Greeting: Hello world

恭喜!你已经成功运行了一个带有 gRPC 的客户端-服务器应用。

更新 gRPC 服务

在本节中,你将通过增加一个额外的服务器方法来更新应用。gRPC 服务是通过 协议缓冲区 定义的。要了解如何在 .proto 文件中定义服务,请参阅 基础教程。目前你只需要知道的是,服务器和客户端存根都有一个 SayHello() RPC 方法,它从客户端接收 HelloRequest 参数,并返回来自服务器的 HelloReply,该方法定义如下:

// 问候服务定义。
service Greeter {
  // 发送问候
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 请求消息,包含用户的姓名。
message HelloRequest {
  string name = 1;
}

// 响应消息,包含问候语
message HelloReply {
  string message = 1;
}

打开 helloworld/helloworld.proto 文件并添加一个新的 SayHelloAgain() 方法,具有相同的请求和响应类型:

// 问候服务定义。
service Greeter {
  // 发送问候
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // 发送另一个问候
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// 请求消息,包含用户的姓名。
message HelloRequest {
  string name = 1;
}

// 响应消息,包含问候语
message HelloReply {
  string message = 1;
}

记得保存文件!

重新生成 gRPC 代码

在使用新服务方法之前,你需要重新编译更新的 .proto 文件。

仍在 examples/helloworld 目录下,运行以下命令:

protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    helloworld/helloworld.proto

这将重新生成 helloworld/helloworld.pb.gohelloworld/helloworld_grpc.pb.go 文件,其中包含:

  • 填充、序列化和检索 HelloRequestHelloReply 消息类型的代码。

  • 生成的客户端和服务器代码。

更新并运行应用

你已经重新生成了服务器和客户端代码,但仍然需要在示例应用的手写部分实现并调用新方法。

更新服务器

打开 greeter_server/main.go 并添加以下函数:

func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
        return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil
}

更新客户端

打开 greeter_client/main.go,并在 main() 函数的末尾添加以下代码:

r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: *name})
if err != nil {
        log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())

记得保存你的更改。

运行!

像之前一样运行客户端和服务器。从 examples/helloworld 目录执行以下命令:

  1. 运行服务器:

    go run greeter_server/main.go
  2. 从另一个终端运行客户端,这次添加一个名字作为命令行参数:

    go run greeter_client/main.go --name=Alice

    你将看到以下输出:

    Greeting: Hello Alice
    Greeting: Hello again Alice