在 Go 中实现一个简单的 gRPC 客户端和服务端,可以按照以下步骤进行。
1. 安装 gRPC 和相关工具
首先,需要安装 protobuf
编译器和 protoc-gen-go
插件:
# 安装protoc
brew install protobuf
# 安装protoc-gen-go和protoc-gen-go-grpc插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
将$GOPATH/bin
添加到系统的环境变量中,以便 protoc
能找到插件。
2. 定义 gRPC 服务
创建一个 .proto
文件来定义服务接口。
proto/helloworld.proto:
syntax = "proto3";
package helloworld;
option go_package = "example.com/helloworld";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
3. 生成 gRPC 代码
在命令行中,执行 protoc
生成 Go 代码:
protoc --go_out=. --go-grpc_out=. proto/helloworld.proto
4. 实现服务端
创建一个 gRPC 服务端来实现接口中的 SayHello
方法。
server.go:
Go
package main
import (
"context"
"fmt"
"log"
"net"
"google.golang.org/grpc"
pb "example.com/helloworld"
)
type server struct {
pb.UnimplementedGreeterServer
}
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Printf("Server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
5. 实现客户端
创建一个客户端来调用 SayHello
方法。
client.go:
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/grpc"
pb "example.com/helloworld"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("Did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
name := "world"
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("Could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
6. 运行示例
编译并运行服务端:
Go
go run server.go
在另一个终端中,运行客户端:
Go
go run client.go
客户端将输出类似以下内容:
Go
Greeting: Hello world
Go
解释
.proto 文件定义了服务接口及消息格式。
protoc 命令生成了 Go 代码(服务端和客户端的接口)。
服务端实现了 Greeter 服务并启动了 gRPC 服务器。
客户端连接到服务端并调用 SayHello 方法。
你可以根据需要进一步扩展这个示例。