grpc使用起来很HAPPY。以最近做的一个评论微服务举个栗子。
主要就是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把它编译成对应的语言代码。 首先安装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 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 -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)
差不多就酱了。