grpc使用一览子
- 2019 年 11 月 21 日
- 笔记
grpc使用起来很HAPPY。以最近做的一个评论微服务举个栗子。
创建proto文件。
主要就是request, response两大类 base_req.proto
syntax = "proto3"; package customer; // The service definition. service CommentReq { // Create a new BaseReq - A simple RPC rpc CreateComment (CommentRequest) returns (CommonResponse) {} rpc DeleteComment (CommentRequest) returns (CommonResponse) {} rpc ListComment (ListCommentRequest) returns (ListCommentResponse) {} rpc CommentCount (CommentCountRequest) returns (CommonResponse) {} } // Request message for creating a new customer message CommentRequest { int64 app = 1; Comment comment = 2; } message CommonResponse { int64 err = 1; string err_msg = 2; string extra = 3; } message CommentCountRequest { int64 app = 1; int64 target_id = 2; int64 source = 3; } message ListCommentRequest { int64 app = 1; int64 target_id = 2; int64 source = 3; int64 last_id = 4; int64 count = 5; string order = 6; } message ListCommentResponse { int64 err = 1; string err_msg = 2; int64 last_id = 3; repeated Comment comment = 4; } message Comment { int64 comment_id = 1; string content = 2; int64 creator_id = 3; int64 creator_source = 4; int64 reply_uid = 5; int64 reply_source = 6; int64 target_id = 7; // 评论来源主体的id,可能是视频,帖子 int64 source = 8; // 评论来源主体的来源,可能是1,2 int64 created_at = 9; string extra = 10; // 一个json dump的字符串 }
安装protobuf
然后,要用protobuf把它编译成对应的语言代码。 首先安装protoc,偷个懒,别人早就编译好了。直接用就行。
go get -u github.com/golang/protobuf/protoc-gen-go wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zip mkdir protoc cd protoc mv ../protoc-3.6.1-linux-x86_64.zip . unzip protoc-3.6.1-linux-x86_64.zip export PATH=$PATH:/home/protoc/bin
定位到.proto的目录下,使用这个命令生成go的对应文件
protoc --go_out=plugins=grpc:. base_req.proto
如果proto文件无误,目录下将出现base_req.pb.go
文件。
go使用grpc
首先go get下面的东东
go get google.golang.org/grpc/reflection go get github.com/golang/protobuf/proto go get google.golang.org/grpc
直接来代码了: 服务端启动:
package main import ( pb "base_req" "server" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterCommentReqServer(s, &server.Server{}) pb.RegisterLikeReqServer(s, &server.Server{}) // Register reflection service on gRPC server. reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
server文件,注意,proto定义的函数都要实现。
package server import ( pb "base_req" "golang.org/x/net/context" ) type Server struct{} // SayHello implements helloworld.GreeterServer func (s *Server) CreateComment(ctx context.Context, in *pb.CommentRequest) (*pb.CommonResponse, error) { ... return &pb.CommonResponse{Err: 0, ErrMsg: in.Comment.Content}, nil } .... 省略10000字
客户端:
conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewCommentReqClient(conn) db := sqlutils.GetCommentDB() ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() // 执行函数了!! resp, err := c.CreateComment(ctx, &pb.CommentRequest{App: 2, Comment: &pb.Comment{ Content: "hello", CreatorId: 123, CreatorSource: 456, ReplyUid: 0, ReplySource: 456, TargetId: 1, Source: 2, Extra: "", }})
python客户端
首先把库装好
python -m pip install grpcio --ignore-installed python -m pip install grpcio-tools googleapis-common-protos pip install protobuf==3.6.0 pip install git+https://github.com/kaporzhu/protobuf-to-dict.git
生成py版的proto代码文件
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. base_req.proto
此时,应该出现了base_req_pb2.py和base_req_pb2_grpc.py文件,把它cp到项目中去。引用它。
单向流:
import grpc import base_req_pb2 import base_req_pb2_grpc channel = grpc.insecure_channel(COMMUNITY_RPC_URL) comment_stub = base_req_pb2_grpc.CommentReqStub(channel) response = comment_stub.CreateComment(base_req_pb2. CommentRequest( app=2, comment=base_req_pb2. Comment( content=self.content, creator_id=int(self.creator_id), creator_source=int(self.creator_source), reply_uid=int(self.reply_uid), reply_source=int(self.reply_source), target_id=int(self.target_id), source=int(self.source), extra=self.extra, )))
双向流:
channel = grpc.insecure_channel("119.29.46.85:30112") read_stub = msg_proxy_pb2_grpc.MsgReadProxyStub(channel) secret_id = "2166479cc7c24166afcfa545e5" secret_key = "097751e9bb2741b2ad9eabe327" timestamp = str(int(time.time())) msg = msg_proxy_pb2.Msg( SecretId=secret_id, Signature=gen_sign(secret_id, secret_key, timestamp), Timestamp=timestamp, Topic="float_object_detect", GroupId="testpig", JobID="123", ) def ge_req(): yield msg req = ge_req() response = read_stub.ReadSubscribeTopic(req) for rec in response: print(rec.Buffer)
差不多就酱了。