gRPC
gRPC入门刚学习gRPC的时候,对stream中client和server的操作一直很困惑,为什么除了普通的Send和Recv还有额外的函数,而这些函数之间怎么区分? 后来通过自己编写proto文件,逐个server的相关接口,才明白这些接口是protoc在生成pb.go时同时生成的,对于不同的stream方式生成的函数也不同 SIMPLE RPC首先我们定义最简单的接口GetFeature如下,结构类型的定义就不列出了,大家可以参看https://grpc.io/docs/tutorials/basic/go.html中的定义 service WdyRoute {
// A simple RPC.
rpc GetFeature(Point) returns (Feature) {}
}
执行编译 protoc -I wdyroute/ wdyroute/wdy_route.proto --go_out=plugins=grpc:wdyroute 查看生成的pg.go文件 客户端可以看到主要生成了以下几个内容
func NewWdyRouteClient(cc *grpc.ClientConn) WdyRouteClient {
return &wdyRouteClient{cc}
}
server api主要生成以下内容:
func RegisterWdyRouteServer(s *grpc.Server,srv WdyRouteServer) {
s.RegisterService(&_WdyRoute_serviceDesc,srv)
}
SERVER-to-client streaming RPC定义接口在proto文件中service WdyRoute中增加 rpc ListFeatures(Rectangle) returns (stream Feature) {}
执行编译 protoc -I wdyroute/ wdyroute/wdy_route.proto --go_out=plugins=grpc:wdyroute
查看生成的pb.go文件 客户端pb.go文件中相比之前还增加了
// A server-to-client streaming RPC.
//
// Obtains the Features available within the given Rectangle. Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field),as the rectangle may cover a large area and contain a
// huge number of features.
ListFeatures(ctx context.Context,in *Rectangle,opts ...grpc.CallOption) (WdyRoute_ListFeaturesClient,error)
func (c *wdyRouteClient) ListFeatures(ctx context.Context,error) {
stream,err := grpc.NewClientStream(ctx,&_WdyRoute_serviceDesc.Streams[0],"/wdyroute.WdyRoute/ListFeatures",opts...)
if err != nil {
return nil,err
}
x := &wdyRouteListFeaturesClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil,err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil,err
}
return x,nil
}
type WdyRoute_ListFeaturesClient interface {
Recv() (*Feature,error)
grpc.ClientStream
}
type wdyRouteListFeaturesClient struct {
grpc.ClientStream
}
func (x wdyRouteListFeaturesClient) Recv() (Feature,error) {
m := new(Feature)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil,err
}
return m,nil
}
server apiserver端代码相比之前增加
type WdyRouteServer interface {
...
ListFeatures(*Rectangle,WdyRoute_ListFeaturesServer) error
...
}
WdyRoute_ListFeaturesServer用于server发送stream数据
func _WdyRoute_ListFeatures_Handler(srv interface{},stream grpc.ServerStream) error {
m := new(Rectangle)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(WdyRouteServer).ListFeatures(m,&wdyRouteListFeaturesServer{stream})
}
type WdyRoute_ListFeaturesServer interface {
Send(*Feature) error
grpc.ServerStream
}
type wdyRouteListFeaturesServer struct {
grpc.ServerStream
}
func (x *wdyRouteListFeaturesServer) Send(m *Feature) error {
return x.ServerStream.SendMsg(m)
}
A CLIENT-to-server streaming RPC.定义接口在proto文件service WdyRoute中增加 rpc RecordRoute(stream Point) returns (RouteSummary) {}
执行编译 protoc -I wdyroute/ wdyroute/wdy_route.proto --go_out=plugins=grpc:wdyroute
查看生成的pb.go文件 客户端
// A client-to-server streaming RPC.
//
// Accepts a stream of Points on a route being traversed,returning a
// RouteSummary when traversal is completed.
RecordRoute(ctx context.Context,opts ...grpc.CallOption) (WdyRoute_RecordRouteClient,error)
WdyRoute_RecordRouteClient用于client发送stream数据。
func (c *wdyRouteClient) RecordRoute(ctx context.Context,&_WdyRoute_serviceDesc.Streams[1],"/wdyroute.WdyRoute/RecordRoute",err
}
x := &wdyRouteRecordRouteClient{stream}
return x,nil
}
type WdyRoute_RecordRouteClient interface {
Send(*Point) error
CloseAndRecv() (*RouteSummary,error)
grpc.ClientStream
}
type wdyRouteRecordRouteClient struct {
grpc.ClientStream
}
func (x *wdyRouteRecordRouteClient) Send(m *Point) error {
return x.ClientStream.SendMsg(m)
}
func (x wdyRouteRecordRouteClient) CloseAndRecv() (RouteSummary,error) {
if err := x.ClientStream.CloseSend(); err != nil {
return nil,err
}
m := new(RouteSummary)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil,nil
}
server apiserver端代码相比之前增加
type WdyRouteServer interface {
...
// A client-to-server streaming RPC.
//
// Accepts a stream of Points on a route being traversed,returning a
// RouteSummary when traversal is completed.
RecordRoute(WdyRoute_RecordRouteServer) error
...
}
WdyRoute_RecordRouteServer 用于server接收数据.
func _WdyRoute_RecordRoute_Handler(srv interface{},stream grpc.ServerStream) error {
return srv.(WdyRouteServer).RecordRoute(&wdyRouteRecordRouteServer{stream})
}
type WdyRoute_RecordRouteServer interface {
SendAndClose(*RouteSummary) error
Recv() (*Point,error)
grpc.ServerStream
}
type wdyRouteRecordRouteServer struct {
grpc.ServerStream
}
func (x *wdyRouteRecordRouteServer) SendAndClose(m *RouteSummary) error {
return x.ServerStream.SendMsg(m)
}
func (x wdyRouteRecordRouteServer) Recv() (Point,error) {
m := new(Point)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil,nil
}
A Bidirectional streaming RPC.定义接口在proto文件中service WdyRoute中增加 //
// Accepts a stream of RouteNotes sent while a route is being traversed,// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
执行编译 protoc -I wdyroute/ wdyroute/wdy_route.proto --go_out=plugins=grpc:wdyroute
查看生产的pb.go文件 客户端
// A Bidirectional streaming RPC.
//
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
RouteChat(ctx context.Context,opts ...grpc.CallOption) (WdyRoute_RouteChatClient,error)
WdyRoute_RouteChatClient 用于client发送stream数据。
func (c *wdyRouteClient) RouteChat(ctx context.Context,&_WdyRoute_serviceDesc.Streams[2],"/wdyroute.WdyRoute/RouteChat",err
}
x := &wdyRouteRouteChatClient{stream}
return x,nil
}
type WdyRoute_RouteChatClient interface {
Send(*RouteNote) error
Recv() (*RouteNote,error)
grpc.ClientStream
}
type wdyRouteRouteChatClient struct {
grpc.ClientStream
}
func (x *wdyRouteRouteChatClient) Send(m *RouteNote) error {
return x.ClientStream.SendMsg(m)
}
func (x wdyRouteRouteChatClient) Recv() (RouteNote,error) {
m := new(RouteNote)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil,nil
}
server apiserver端代码相比之前增加
type WdyRouteServer interface {
...
// A Bidirectional streaming RPC.
//
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
RouteChat(WdyRoute_RouteChatServer) error
...
}
WdyRoute_RouteChatServer 用于server接收和发送数据.
func _WdyRoute_RouteChat_Handler(srv interface{},stream grpc.ServerStream) error {
return srv.(WdyRouteServer).RouteChat(&wdyRouteRouteChatServer{stream})
}
type WdyRoute_RouteChatServer interface {
Send(*RouteNote) error
Recv() (*RouteNote,error)
grpc.ServerStream
}
type wdyRouteRouteChatServer struct {
grpc.ServerStream
}
func (x *wdyRouteRouteChatServer) Send(m *RouteNote) error {
return x.ServerStream.SendMsg(m)
}
func (x wdyRouteRouteChatServer) Recv() (RouteNote,error) {
m := new(RouteNote)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil,nil
}
遇到问题原因是命令写错了。 (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |