gRPC使用的分析

看了docker的源码就不得不了解一下gRPC这个鬼东西。下面借鉴一下别人的实例,让我这个初次接触的人做一个,最直接的分析。
  1. 首先编译安装protobuf 工具。
    go get google.golang.org/grpc go get -u github.com/golang/protobuf/{proto,protoc-gen-go} //下载proto转换为go语言的工具 export PATH=$PATH:$GOPATH/bin // 将其加入环境变量

  2. 创建一个rpcsrv.proto文件。
    syntax = "proto3"; package xcl; enum UserStatus { OFFLINE = 0; ONLINE = 1; } message UserInfo { int32 id = 1; string name = 2; UserStatus status = 3 ; } message UserID { int32 id = 1; } message funcResponse { string reply = 1; } // 定义将要用到的rpc调用方法,参数和返回值都在上面进行了定义 service UserService { rpc Login(UserInfo) returns (funcResponse){}; rpc Logout(UserID) returns (funcResponse){}; }

  3. 编译生成对应的go代码。
    protoc rpcsrv.go --go_out=plugins=grpc:

    rpcsrv.pb.go文件如下,主要就是生成了相应的结构体:
    type UserInfo struct { Idint32`protobuf:"varint,1,opt,name=id" json:"id,omitempty"` Namestring`protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Status UserStatus `protobuf:"varint,3,opt,name=status,enum=xcl.UserStatus" json:"status,omitempty"` } type UserID struct { Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` } type FuncResponse struct { Reply string `protobuf:"bytes,1,opt,name=reply" json:"reply,omitempty"` }

  4. 变成服务端程序:
    package main import ( pb "xcl" "log" "net" "os" "golang.org/x/net/context" "google.golang.org/grpc" ) func main() { log.SetOutput(os.Stdout) lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterUserServiceServer(s, &server{}) log.Println("Server......") s.Serve(lis) } const ( port = ":50051"//监听的端口 ) type server struct{}//定义server的结构体 // 实现Login的方法,参数和返回值与最上面定义的proto都有对应的关系。 func (s *server) Login(ctx context.Context, usr *pb.UserInfo) (*pb.FuncResponse, error) { log.Println("Server...... Login() UserInfo:", usr) usr.Id = 100 strId := "100" //strconv.Itoa(usr.Id) return &pb.FuncResponse{Reply: strId}, nil } // 实现Logout的方法 func (s *server) Logout(ctx context.Context, uid *pb.UserID) (*pb.FuncResponse, error) { log.Println("Server...... Logout() UserID:", uid) return &pb.FuncResponse{Reply: "Logout Successed."}, nil }

  5. 【gRPC使用的分析】定义客户端:
    package main import ( "log" "os" "strconv" pb "xcl" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( address = "localhost:50051"// 服务器的套接字 ) func main() { log.SetOutput(os.Stdout) conn, err := grpc.Dial(address)//首先创建一个 gRPC channel 和服务器交互 if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() // 一旦 gRPC channel 建立起来,我们需要一个客户端存根去执行RPC。我们通过.proto生成的pb包提供的NewUserServiceClient方法来完成。 c := pb.NewUserServiceClient(conn) var status pb.UserStatus status = pb.UserStatus_ONLINE userInfo := &pb.UserInfo{ //Id:10,//proto.Int32(10), Name:"XCL-gRPC", //proto.String("XCL-gRPC"), Status: status, }// 直接调用相应的方法,来远程调用服务端。 r, err := c.Login(context.Background(), userInfo) if err != nil { log.Fatalf("登录失败!%v", err) } log.Println("Login():", r)uid, err := strconv.ParseInt(r.Reply, 10, 32) if err != nil { log.Fatalf("非数字%v", err) }userID := &pb.UserID{int32(uid)} out, err := c.Logout(context.Background(), userID) log.Println("Logout():", out) }

参考:
[1] gRPC官方文档

    推荐阅读