在windows环境下安装protocol,并用golang做一个grpc实践 | 青训营

1,572 阅读3分钟

一、windows安装protocol

1、下载protobuf

Releases · protocolbuffers/protobuf (github.com)

选择这个 image.png

解压出一个exe执行文件,保存到GOPATH下的bin文件夹

注意是GOPATH,而非GOROOT

2、下载protoc-gen-go

go get -u github.com/golang/protobuf/protoc-gen-go

在文件管理器打开该目录,找到exe执行文件

image.png

如果没有这个exe执行文件,就在这个文件夹下执行 go build

上两个步骤完成后在GOPATH文件下的bin文件夹中有如下两个执行文件

image.png

3、下载grpc依赖

go get google.golang.org/grpc

二、grpc实践

实践目标:客户端输入的内容转为大写并返回

例如:abcd >> ABCD

1、创建proto/toupper.proto

在“.proto”文件的头部声明中,需要声明“.proto”所使用的Protobuf协议版本,这里使用的是"proto3"。也可以使用旧一点的版本"proto2",两个版本的消息格式有一些细微的不同。 默认的协议版本为"proto2"。

Protobuf支持很多语言,所以它为不同的语言提供了一些可选的声明选项,选项的前面有option关键字。

syntax = "proto3";

package proto;

// The service definition.
service ToUpper{
  // Sends a greeting
  rpc Upper (UpperRequest) returns (UpperReply) {}
}

// The request message
message UpperRequest {
  string name = 1;
}

// The response message
message UpperReply {
  string message = 1;
}

2、创建main/serve.go和main/client.go

serve.go

package main

import (
   pb "toupper/proto"
   "log"
   "net"
   "strings"

   "golang.org/x/net/context"
   "google.golang.org/grpc"
   "google.golang.org/grpc/reflection"
)

const (
   port = ":50051"
)

type server struct{}

func (s *server) Upper(ctx context.Context, in *pb.UpperRequest) (*pb.UpperReply, error) {
   log.Printf("Received: %s", in.Name)
   return &pb.UpperReply{Message: strings.ToUpper(in.Name)}, nil
}

func main() {
   lis, err := net.Listen("tcp", port)
   if err != nil {
      log.Fatalf("failed to listen: %v", err)
   }
   s := grpc.NewServer()
   pb.RegisterToUpperServer(s, &server{})
   // Register reflection service on gRPC server.
   reflection.Register(s)
   if err := s.Serve(lis); err != nil {
      log.Fatalf("failed to serve: %v", err)
   }
}

client.go

package main

import (
   "log"
   "os"

   pb "toupper/proto"
   "golang.org/x/net/context"
   "google.golang.org/grpc"
)

const (
   address = "localhost:50051"
)

func main() {
   // Set up a connection to the server.
   conn, err := grpc.Dial(address, grpc.WithInsecure())
   if err != nil {
      log.Fatalf("did not connect: %v", err)
   }
   defer conn.Close()
   c := pb.NewToUpperClient(conn)

   // Contact the server and print out its response.
   name := "hello world"
   if len(os.Args) > 1 {
      name = os.Args[1]
   }
   r, err := c.Upper(context.Background(), &pb.UpperRequest{Name: name})
   if err != nil {
      log.Fatalf("could not greet: %v", err)
   }
   log.Printf("Response: %s", r.Message)
}

3、编译

protoc -I proto toupper.proto --go_out=plugins=grpc:proto
go build main/client.go
go build main/server.go

注意:第一条指令可能会报错

protoc-gen-go: unable to determine Go import path for "xxxx.proto"
 
Please specify either:
        • a "go_package" option in the .proto source file, or
        • a "M" argument on the command line.
 
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
 
--go_out: protoc-gen-go: Plugin failed with status code 1.

需要在proto文件中添加

option go_package = "../proto";

4、运行

编译完成的项目目录如下所示

image.png

在两个命令窗口分别启动client.exe和server.exe

在client输入:

PS D:\workspace\Go\toupper> .\client.exe
2023/07/26 16:08:16 Response: HELLO WORLD
PS D:\workspace\Go\toupper> .\client.exe asdf
2023/07/26 16:08:31 Response: ASDF

在serve输出:

PS D:\workspace\Go\toupper> .\server.exe
2023/07/26 16:08:16 Received: hello world
2023/07/26 16:08:31 Received: asdf

三、总结

proto文件来预先定义的消息格式。数据包是按照proto文件所定义的消息格式完成二进制码流的编码和解码。proto文件,简单地说,就是一个消息的协议文件,这个协议文件的后缀文件名为“.proto”。 作为演示,下面介绍一个非常简单的proto文件:仅仅定义一个消息结构体,并且该消息结构体也非常简单,仅包含两个字段。

本文总结了在windows下安装protocol,并做了一个grpc实践,非常完整