快速开始
本指南将带你通过一个简单的工作示例开始使用 Go 中的 gRPC。
前提条件
-
Go,Go 的最新两个主要版本之一。
安装说明,请参见 Go 的 [入门指南](https://golang.org/doc/install)。
-
安装说明,请参见 协议缓冲区编译器安装。
-
Go 插件用于协议编译器:
-
使用以下命令安装 Go 的协议编译器插件:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
-
更新你的
PATH
,以便protoc
编译器能够找到这些插件:export PATH="$PATH:$(go env GOPATH)/bin"
-
获取示例代码
示例代码是 grpc-go 仓库的一部分。
-
你可以下载仓库的 zip 文件 并解压,或者克隆仓库:
git clone -b v1.69.2 --depth 1 https://github.com/grpc/grpc-go
-
切换到快速入门示例目录:
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.go
和 helloworld/helloworld_grpc.pb.go
文件,其中包含:
-
填充、序列化和检索
HelloRequest
和HelloReply
消息类型的代码。 -
生成的客户端和服务器代码。
更新并运行应用
你已经重新生成了服务器和客户端代码,但仍然需要在示例应用的手写部分实现并调用新方法。
更新服务器
打开 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
}