Go 使用 Proto

安装

先安装插件,最好指定版本防止出错

go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

编写 proto 文件

syntax = "proto3";  
option go_package = "awesome/demo/helloworld";  
package helloworld;  
  
service Greeter {  
  rpc SayHello (HelloRequest) returns (HelloReply) {}  
}  
  
message HelloRequest {  
  string name = 1;  
}  
  
message HelloReply {  
  string message = 1;  
}

原来的版本是 option go_package = ".;proto";

生成 grpc 代码

进入 demo/helloworld 目录下,

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

这将重新生成 helloworld.pb.gohelloworld_grpc.pb.go 两个文件,其中包含填充、序列化和检索 HelloRequest 和 HelloReply 消息类型的代码,生成的客户端和服务器代码。

服务端代码

创建一个 server 目录,

package main  
  
import (  
    "context"  
    "flag"    
    "fmt"    
    "log"    
    "net"  
    
    pb "demo/helloworld"  
  
    "google.golang.org/grpc"
    )  
  
var (  
    port = flag.Int("port", 50051, "The server port")  
)  
  
// 服务器用于实现 helloworld.GreeterServer。 
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() {  
    flag.Parse()  
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))  
    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)  
    }  
}

创建连接端

package main  
  
import (  
    "context"  
    "flag"    
    "log"    
    "time"  
    pb "awesome/demo/helloworld"  
  
    "google.golang.org/grpc"    
    "google.golang.org/grpc/credentials/insecure"
    )  
  
const (  
    defaultName = "world"  
)  
  
var (  
    addr = flag.String("addr", "localhost:50051", "the address to connect to")  
    name = flag.String("name", defaultName, "Name to greet")  
)  
  
func main() {  
    flag.Parse()  
    // Set up a connection to the server.  
    conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))  
    if err != nil {  
       log.Fatalf("did not connect: %v", err)  
    }  
    defer conn.Close() 
     
    c := pb.NewGreeterClient(conn)  
  
    // Contact the server and print out its response.  
    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())  
}

示例

https://github.com/protocolbuffers/protobuf/tree/main/examples/go

使用 Hugo 构建
主题 StackJimmy 设计