gPPC 生成 Go 代码参考文档

Table of Contents

https://grpc.io/docs/reference/go/generated-code/

生成 Go 的 protobuf package 文件需要在使用 protoc 编译 .proto 文件时使用 protoc-gen-go 插件。

1. 命令行

使用 protobuf 编译器:

protoc -I=libproto --go_out=plugins=grpc:libproto libproto/xxx.proto

2. 服务器接口生成的方法

在 Server 端, .proto 文件中的每一个 service Bar 都会生成如下的函数:

func RegisterBarServer(s *grpc.Server, svr BarServer)

在服务器启动之前,应用程序要自己实现一个 BarServer 接口的具体实现,然后把它注册到 grpc.Server 实例中。

2.1. 一元方法(Unary methods)

这些方法在生成服务接口的时候有如下的签名:

Foo(context.Context, *MsgA) (*MsgB, error)

MsgA 是客户端请求的 protobuf 消息, MsgB 是从服务器返回的 protobuf 消息。

2.2. 服务器流方法(Server-streaming methods)

这些方法在生成服务接口的时候有如下的签名:

Foo(*MsgA, <ServiceName>_FooServer) error

MsgA 是来自客户端的单个请求, <ServiceName>_FooServer 表示 MsgB 的 server-to-client流。

<ServiceName>_FooServer 是一个内嵌 grpc.ServerStream 的如下接口:

type <ServiceName>_FooServer interface {
  Send(*MsgB) error
  grpc.ServerStream
}

服务端的处理器通过 Send 方法向客户端不断的发送 protobuf 消息,流的结束以处理器的 handler 方法为准。

2.3. 客户端流方法(Client-streaming methods)

这些方法在生成服务接口的时候有如下的签名:

Foo(<ServiceName>_FooServer) error

<ServiceName>_FooServer 既可以用来读取从客户端到服务器的消息流,也可以用来发送单个服务器的响应消息。

<ServiceName>_FooServer 是一个内嵌 grpc.ServerStream 的如下接口:

type <ServiceName>_FooServer interface {
    SendAndClose(*MsgA) error
    Recv() (*MsgB, error)
    grpc.ServerStream
}

服务端可以重复的调用 Recv 来获取从客户端发送过来的全部消息。 Recv 一旦返回 (nil, io.EOF) 说明流结束了。 服务端回复消息通过调用 SendAndClose 方法。注意 SendAndClose 只能被调用一次。

2.4. 双向流(Bidi-streaming methods)

这些方法在生成服务接口的时候有如下的签名:

Foo(<ServiceName>_FooServer) error

<ServiceName>_FooServer 既可以访问从客户端到服务器的流也可以访问从服务器到客户端的流。 <ServiceName>_FooServer 内嵌了 grpc.ServerSteam 如下:

type <ServiceName>_FooServer interface {
    Send(*MsgA) error
    Recv() (*MsgB, error)
    grpc.ServerStream
}

服务器端的处理程序可以重复调用 Recv 获取从客户端发来的消息流。 Recv 返回 (nil, io.EOF) 表示客户端流结束了。 回复的流通过重复调用 Send 方法来实现, return 表示发送结束。

3. 客户端接口生成的方法

在客户端测, proto 文件中的每一个 service Bar 也都会生成一个函数: func BarClient(cc *grpc.ClientConn) BarClient , 它会返回 BarClient 接口的具体实现(此接口实现也会存在于生成的 .pb.go 文件中)。

3.1. 一元方法(Unary Methods)

这些方法生成的客户端存根具有以下签名:

(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (*MsgB, error)

MsgA 是客户端的请求, MsgB 是服务器的回包。

3.2. 服务端流方法(Server-Streaming methods)

这些方法生成的客户端存根具有以下签名:

Foo(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

<ServiceName>_FooClient 表示服务器到客户端的 MsgB 的消息流。该流是由内嵌一个 gprc.ClientStream 的接口:

type <ServiceName>_FooClient interface {
    Recv() (*MsgB, error)
    grpc.ClientStream
}

客户端重复调用 Recv 方法来返回服务器回复的消息。当 Recv 接受到 (nil, io.EOF) 表示流结束。

3.3. 客户端流方法(Client-Streaming methods)

这些方法生成的客户端存根具有以下签名:

Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

<ServieName>_FooClient 表示客户端到服务器的 MsgA 消息流。

<ServieName>_FooClient 是一个内嵌了 grpc.ClientStream 的如下接口:

type <ServiceName>_FooClient interface {
    Send(*MsgA) error
    CloseAndRecv() (*MsgA, error)
    grpc.ClientStream
}

客户端可以重复调用 Send 方法想服务器发送消息,最后调用 CloseAndRecv() 结束发送等待服务器回包。

3.4. 双向流方法(Bidi-Streaming methods)

这些方法生成的客户端存根具有以下签名:

Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

<ServiceName>_FooClient 表示客户端到服务器和服务器到客户端的双向流。它是内嵌了 grpc.ClientStream 的如下接口:

type <ServiceName>_FooClient interface {
    Send(*MsgA) error
    Recv() (*MsgB, error)
    grpc.ClientStream
}

客户端重复调用 Send 方法发送消息,同时可以重复调用 Recv 方法接受消息。

服务器到客户端的流通过返回 (nil, io.EOF) 终结,客户端到服务器的流通过客户端调用 CloseSend 来结束。

4. 包和命名空间

protoc 编译器调用 -go_out=plugins=grpc: 时, proto package 会被转换成 Go 的包,跟 protoc-gen-go 插件不加 grpc 效果相同。

因此,如果 foo.protopackage foo 中声明,那么 foo.pb.go 生成的文件也会在 Go 的包 foo 包中。

First created: 2020-05-21 15:05:55
Last updated: 2022-12-11 Sun 12:49
Power by Emacs 27.1 (Org mode 9.4.4)