加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

gRPC

发布时间:2020-12-16 09:39:57 所属栏目:大数据 来源:网络整理
导读:gRPC入门 SIMPLE RPC 客户端 server api SERVER-to-client streaming RPC 定义接口 客户端 server api A CLIENT-to-server streaming RPC 定义接口 客户端 server api A Bidirectional streaming RPC 定义接口 客户端 server api 遇到问题 gRPC入门 刚学习gR
  • gRPC入门
    • SIMPLE RPC
      • 客户端
      • server api
    • SERVER-to-client streaming RPC
    • 定义接口
      • 客户端
      • server api
    • A CLIENT-to-server streaming RPC
      • 定义接口
      • 客户端
      • server api
    • A Bidirectional streaming RPC
      • 定义接口
      • 客户端
      • server api
    • 遇到问题

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文件

客户端

可以看到主要生成了以下几个内容

  1. 一个WdyRouteClient的interface,接口定义方法GetFeature.

    // Client API for WdyRoute service
    
    type WdyRouteClient interface {
    
       // A simple RPC.
    
       //
    
       // Obtains the feature at a given position.
    
       //
    
       // A feature with an empty name is returned if there's no feature at the given
    
       // position.
    
       GetFeature(ctx context.Context,in Point,opts ...grpc.CallOption) (Feature,error)
    
    }

    ?

  2. 一个名为wdyRouteClient的实现,实现了方法GetFeature.

    type wdyRouteClient struct {
    
       cc *grpc.ClientConn
    
    }
    
    func (c wdyRouteClient) GetFeature(ctx context.Context,in *Point,error) {
    
       out := new(Feature)
    
       err := grpc.Invoke(ctx,"/wdyroute.WdyRoute/GetFeature",in,out,c.cc,opts...)
    
       if err != nil {
    
           return nil,err
    
       }
    
       return out,nil
    
    }

    ?

  3. 一个函数NewWdyRouteClient用来创建WdyRouteClient,如下:

func NewWdyRouteClient(cc *grpc.ClientConn) WdyRouteClient {

    return &wdyRouteClient{cc}

}

server api

主要生成以下内容:

  1. 生成了名为WdyRouteServer的interface,方法为GetFeature;

    type WdyRouteServer interface {
    
       // A simple RPC.
    
       //
    
       // Obtains the feature at a given position.
    
       //
    
       // A feature with an empty name is returned if there's no feature at the given
    
       // position.
    
       GetFeature(context.Context,Point) (Feature,error)
    
    }

    ?

  2. 名为 _WdyRoute_GetFeature_Handler 的handler 用来处理客户端的GetFeature的RPC请求.

    func _WdyRoute_GetFeature_Handler(srv interface{},ctx context.Context,dec func(interface{}) error,interceptor grpc.UnaryServerInterceptor) (interface{},error) {
    in := new(Point)
    if err := dec(in); err != nil {
        return nil,err
    }
    if interceptor == nil {
        return srv.(WdyRouteServer).GetFeature(ctx,in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,FullMethod: "/wdyroute.WdyRoute/GetFeature",}
    handler := func(ctx context.Context,req interface{}) (interface{},error) {
        return srv.(WdyRouteServer).GetFeature(ctx,req.(*Point))
    }
    return interceptor(ctx,info,handler)
    }

    ?

  3. 还有注册server的函数如下:

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文件中相比之前还增加了

  1. type WdyRouteClient interface 中相比之前增加了方法 ListFeatures,该方法返回一个WdyRoute_ListFeaturesClient的interface,如下:
// 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)

WdyRoute_ListFeaturesClient 用于client读取stream数据。

  1. WdyRouteClient interface 的实例wdyRouteClient 也实现了方法 ListFeatures 如下:
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

}
  1. .新的接口 WdyRoute_ListFeaturesClient,该接口定义了方法Recv 用于client接受数据;
type WdyRoute_ListFeaturesClient interface {

    Recv() (*Feature,error)

    grpc.ClientStream

}
  1. WdyRoute_ListFeaturesClient interface的实例 wdyRouteListFeaturesClient的定义;
type wdyRouteListFeaturesClient struct {

    grpc.ClientStream

}
  1. wdyRouteListFeaturesClient 实现方法Recv用于客户端从server读取stream数据;
func (x wdyRouteListFeaturesClient) Recv() (Feature,error) {

    m := new(Feature)

    if err := x.ClientStream.RecvMsg(m); err != nil {

        return nil,err

    }

    return m,nil

}

server api

server端代码相比之前增加

  1. WdyRouteServer interface中相比之前增加了方法 ListFeatures,方法ListFeatures的第二个参数为WdyRoute_ListFeaturesServer interface;
type WdyRouteServer interface {

    ...

    ListFeatures(*Rectangle,WdyRoute_ListFeaturesServer) error

    ...

}

WdyRoute_ListFeaturesServer用于server发送stream数据

  1. _WdyRoute_ListFeatures_Handler
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})

}
  1. WdyRoute_ListFeaturesServer interface,定义了方法 Send 用于server发送stream数据
type WdyRoute_ListFeaturesServer interface {

    Send(*Feature) error

    grpc.ServerStream

}
  1. WdyRoute_ListFeaturesServer interface的实例 wdyRouteListFeaturesServer 以及方法Send的实现
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文件

客户端

  1. type WdyRouteClient interface增加方法 RecordRoute
// 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数据。

  1. wdyRouteClient 新实现了方法 RecordRoute,该方法返回WdyRoute_RecordRouteClient interface
func (c *wdyRouteClient) RecordRoute(ctx context.Context,&_WdyRoute_serviceDesc.Streams[1],"/wdyroute.WdyRoute/RecordRoute",err

    }

    x := &wdyRouteRecordRouteClient{stream}

    return x,nil

}
  1. WdyRoute_RecordRouteClient interface的定义,该接口含有方法Send和CloseAndRecv,用于发送stream数据。
type WdyRoute_RecordRouteClient interface {

    Send(*Point) error

    CloseAndRecv() (*RouteSummary,error)

    grpc.ClientStream

}
  1. WdyRoute_RecordRouteClient interface的实例wdyRouteRecordRouteClient以及对方法Send和CloseAndRecv的定义
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 api

server端代码相比之前增加

  1. WdyRouteServer interface中相比之前增加了方法 RecordRoute,方法 RecordRoute 的参数为 WdyRoute_RecordRouteServer interface;
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接收数据.

  1. _WdyRoute_RecordRoute_Handler
func _WdyRoute_RecordRoute_Handler(srv interface{},stream grpc.ServerStream) error {

    return srv.(WdyRouteServer).RecordRoute(&wdyRouteRecordRouteServer{stream})

}
  1. WdyRoute_RecordRouteServer interface,定义接口SendAndClose和Recv,用于server接收数据.
type WdyRoute_RecordRouteServer interface {

    SendAndClose(*RouteSummary) error

    Recv() (*Point,error)

    grpc.ServerStream

}
  1. WdyRoute_RecordRouteServer interface的实例wdyRouteRecordRouteServer以及对方法SendAndClose和Recv的实现
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文件

客户端

  1. type WdyRouteClient interface增加方法 RecordRoute
// 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数据。

  1. wdyRouteClient对方法RouteChat的实现
func (c *wdyRouteClient) RouteChat(ctx context.Context,&_WdyRoute_serviceDesc.Streams[2],"/wdyroute.WdyRoute/RouteChat",err

    }

    x := &wdyRouteRouteChatClient{stream}

    return x,nil

}
  1. WdyRoute_RouteChatClient interface 的定义
type WdyRoute_RouteChatClient interface {

    Send(*RouteNote) error

    Recv() (*RouteNote,error)

    grpc.ClientStream

}
  1. WdyRoute_RouteChatClient interface 的实例wdyRouteRouteChatClient的定义以及对方法Send和Recv的实现
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 api

server端代码相比之前增加

  1. WdyRouteServer interface中相比之前增加了方法 RouteChat,方法 RouteChat 的参数为 WdyRoute_RouteChatServer interface;
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接收和发送数据.

  1. _WdyRoute_RouteChat_Handler
func _WdyRoute_RouteChat_Handler(srv interface{},stream grpc.ServerStream) error {

    return srv.(WdyRouteServer).RouteChat(&wdyRouteRouteChatServer{stream})

}
  1. WdyRoute_RouteChatServer interface 的定义,该接口定义了方法Send,Recv用于从stream发送和接受数据
type WdyRoute_RouteChatServer interface {

    Send(*RouteNote) error

    Recv() (*RouteNote,error)

    grpc.ServerStream

}
  1. WdyRoute_RouteChatServer interface 的实例wdyRouteRouteChatServer
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

}

遇到问题

原因是命令写错了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读