go-grpc学习实例

Post not found: go/go-grpc的使用 go-grpc的使用 中搭建了完整的开发环境,并且测试程序也能跑起来了。
下面就是参考测试程序写的服务端和客户端样例。

proto3

先定义 .proto

/*
2018.04.06:
GIS服务接口,目前支持以下服务:
- 查询状态
*/

syntax = "proto3";

package gisRPC;

// The gisRPC service definition.
service gisRPCService {
// 查询终端参数0x8104
rpc queryStatus (queryStatusRequest) returns (queryStatusReply) {}
}

message queryStatusRequest {
string cellphone = 1;
}

message ParamInfo{
uint32 id = 1;
uint32 length = 2;
string value = 3;
}

// The response message containing the greetings
message queryStatusReply {
uint32 count = 1;
repeated ParamInfo paramInfo = 2;
}

编译 .proto 文件

protoc --go_out=plugins=grpc:. *.proto

建立服务端程序

我的这个程序是在另一个主文件中使用 go routine 调用的。所以这里没有 main 函数

package main

import (
"fmt"
"log"
"net"

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

const (
port = ":40051"
)

// server .
type server struct{}

// SayHello implements helloworld.GreeterServer
func (s *server) QueryStatus(ctx context.Context, in *pb.QueryStatusRequest) (*pb.QueryStatusReply, error) {
piSlice := make([]* pb.ParamInfo, 0,10)

piSlice = append(piSlice, &pb.ParamInfo{1,2,"vs"})
piSlice = append(piSlice, &pb.ParamInfo{2,3,"vss"})
piSlice = append(piSlice, &pb.ParamInfo{3,5,"vssis"})

fmt.Print(piSlice)
return &pb.QueryStatusReply{Count: 3, ParamInfo:piSlice}, nil
}

func RpcServe() {

lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGisRPCServiceServer(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)
}
}

建立客户端程序

package main

import (
"google.golang.org/grpc"
"log"
"os"
"time"
"golang.org/x/net/context"

pb "./gisRPC"
)

const (
address = "localhost:40051"
defaultName = "123123123123"
)

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.NewGisRPCServiceClient(conn)

// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
r, err := c.QueryStatus(ctx, &pb.QueryStatusRequest{Cellphone: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("server response: %d items - %+v", r.Count, r.ParamInfo)
}

先运行服务端程序,然后运行客户端程序,会打印出交互的记录。
除了安装 pb 的时候费劲之外,用起来真的好方便呀。