這篇文章將介紹如何使用 Go 語言開發基于 Protocol Buffers (Proto 文件) 協議的 gRPC 服務器端(Server)和客戶端(Client)。通過該文章使讀者掌握基本的 gRPC Server、Client 開發步驟、工具和方法。
1. 安裝開發工具
確保安裝以下工具和庫:
- Go 語言開發工具:正確配置 Go 語言開發環境
- Protocol Buffers Compiler (protoc):用于編譯
.proto文件 - gRPC 和 Protocol Buffers 的 Go 插件:用于生成 Server、Client 框架代碼
go get google.golang.org/grpc
go get google.golang.org/protobuf/cmd/protoc-gen-go
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
2. 創建 Proto 文件
創建一個 .proto 文件,定義消息結構和服務方法。例如,創建一個名為 example.proto 的文件,內容如下:
syntax = "proto3";
package example;
// 定義消息
message Request {
string name = 1;
}
message Response {
string message = 1;
}
// 定義服務
service Greeter {
rpc SayHello(Request) returns (Response);
}
3. 生成 Go 框架代碼
使用 protoc 命令生成 Go 框架代碼:
# --go_out 消息代碼輸出文件夾, --go-grpc_out gRPC代碼輸出文件夾
protoc --go_out=. --go-grpc_out=. example.proto
生成如下兩個文件:
example.pb.go:包含消息類型、結構定義及消息序列化/反序列化example_grpc.pb.go:包含 gRPC 服務的接口定義和實現
4. 實現 gRPC 服務器
使用上面生成的 Go 消息和服務代碼實現 gRPC 服務器,創建一個 Go 文件(例如 server.go)內容如下:
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "path/to/your/generated/package" // 替換為生成代碼的實際包路徑
)
// server 結構體實現了 GreeterServer 接口
type server struct {
pb.UnimplementedGreeterServer // 嵌入未實現的服務器
}
// 實現 SayHello 方法
func (s *server) SayHello(ctx context.Context, req *pb.Request) (*pb.Response, error) {
return &pb.Response{Message: "Hello " + req.Name}, nil
}
func main() {
// 創建 gRPC 服務器
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// 監聽端口
listener, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
log.Println("Server is running on port :50051")
if err := s.Serve(listener); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
5. 實現 gRPC 客戶端
實現 gRPC 客戶端,創建一個 Go 文件(例如 client.go)內容如下:
package main
import (
"context"
"log"
"time"
"google.golang.org/grpc"
pb "path/to/your/generated/package" // 替換為生成代碼的實際包路徑
)
func main() {
// 連接到 gRPC 服務器
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("Did not connect: %v", err)
}
defer conn.Close()
client := pb.NewGreeterClient(conn)
// 設置超時
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 調用 SayHello 方法
response, err := client.SayHello(ctx, &pb.Request{Name: "World"})
if err != nil {
log.Fatalf("Could not greet: %v", err)
}
log.Printf("Response from server: %s", response.Message)
}
6. 運行服務器和客戶端
- 運行 gRPC 服務器:
go run server.go
- 在另一個終端運行 gRPC 客戶端:
go run client.go
總結
通過以上步驟,我們使用 Go 語言基于 Protocol Buffers 開發了完整的 gRPC 服務器端和客戶端。讀者可以參考上面介紹的工具、方法和步驟,實現自己的業務需求。