前期准备
工具安装及使用
grpc开发
编写proto文件
proto文件是符合Protocol Buffers语言规范的数据交换协议文件,就像以前WebService定义服务时使用的XML文件。现在一般都是用proto3了,这里创建一个名为 hello.proto 的文件,放到项目的proto目录下:
syntax = "proto3";option go_package="/proto";package Business;service Hello {rpc Say (SayRequest) returns (SayResponse);
}message SayResponse {string Message = 1;
}message SayRequest {string Name = 1;
}
这个协议很简单,有个名字为Hello的服务,提供一个名字为Say的rpc方法,这个方法有输入输出,输入信息中有一个名为Name的参数,输出信息中有一个名为Message的返回值。
生成grpc代码
在项目根目录执行执行: protoc --go_out=. --go-grpc_out=. ./proto/hello_grpc.proto
go mod init
# 初始化项目名为test
go mod init test# 安装依赖包
go mod tidy
服务端代码编写
// server.go
package mainimport ("context""fmt""net""test/proto""google.golang.org/grpc"
)type server struct {proto.UnimplementedHelloServer
}func (s *server) Say(ctx context.Context, req *proto.SayRequest) (*proto.SayResponse, error) {fmt.Println("request:", req.Name)return &proto.SayResponse{Message: "Hello " + req.Name}, nil
}func main() {listen, err := net.Listen("tcp", ":8001")if err != nil {fmt.Printf("failed to listen: %v", err)return}s := grpc.NewServer()proto.RegisterHelloServer(s, &server{})//reflection.Register(s)defer func() {s.Stop()listen.Close()}()fmt.Println("Serving 8001...")err = s.Serve(listen)if err != nil {fmt.Printf("failed to serve: %v", err)return}
}
客户端代码编写
// client.go
package mainimport ("bufio""context""fmt""os""test/proto""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"
)func main() {var serviceHost = "127.0.0.1:8001"conn, err := grpc.NewClient(serviceHost, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {fmt.Println(err)}defer conn.Close()client := proto.NewHelloClient(conn)rsp, err := client.Say(context.TODO(), &proto.SayRequest{Name: "test",})if err != nil {fmt.Println(err)}fmt.Println(rsp)fmt.Println("按回车键退出程序...")in := bufio.NewReader(os.Stdin)_, _, _ = in.ReadLine()
}
验证
# 安装依赖包
go mod tidy# 启动服务端代码
go run server.go
# Serving 8001...# 启动客户端代码
go run client.go
# Message:"Hello test"# 服务端输出
# request: test