您的位置:首页 > 其它

gRPC使用的分析

2016-09-18 22:44 435 查看
看了docker的源码就不得不了解一下gRPC这个鬼东西。下面借鉴一下别人的实例,让我这个初次接触的人做一个,最直接的分析。

首先编译安装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 // 将其加入环境变量


创建一个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){};
}


编译生成对应的go代码。

protoc rpcsrv.go --go_out=plugins=grpc:


rpcsrv.pb.go文件如下,主要就是生成了相应的结构体:

type UserInfo struct {
Id     int32      `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
Name   string     `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"`
}


变成服务端程序:

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
}


定义客户端:

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官方文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gRPC