一、windows安装protocol
1、下载protobuf
Releases · protocolbuffers/protobuf (github.com)
选择这个
解压出一个exe执行文件,保存到GOPATH下的bin文件夹
注意是GOPATH,而非GOROOT
2、下载protoc-gen-go
go get -u github.com/golang/protobuf/protoc-gen-go
在文件管理器打开该目录,找到exe执行文件
如果没有这个exe执行文件,就在这个文件夹下执行 go build
上两个步骤完成后在GOPATH文件下的bin文件夹中有如下两个执行文件
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、运行
编译完成的项目目录如下所示
在两个命令窗口分别启动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实践,非常完整