生成コード(レガシー非ジェネリック)リファレンス
生成コード(レガシー非ジェネリック)リファレンス
grpc プラグイン、protoc-gen-go-grpc を使用して .proto ファイルを protoc でコンパイルした際に生成されるコードについて説明します。
.proto ファイルで gRPC サービスを定義する方法については、「サービス定義」を参照してください。
スレッドセーフ:クライアント側の RPC 呼び出しとサーバー側の RPC ハンドラはスレッドセーフであり、並行 goroutine で実行されることを意図しています。ただし、個々のストリームについては、送受信データは双方向ですが直列的です。したがって、たとえば個々のストリームでは並行読み取りまたは並行書き込みはサポートされません(ただし、読み取りは書き込みと安全に並行して実行できます)。
生成されたサーバーインターフェース上のメソッド
サーバー側では、.proto ファイル内の各 service Bar は、次の関数を生成します。
func RegisterBarServer(s *grpc.Server, srv BarServer)
アプリケーションは、BarServer インターフェースの具象実装を定義し、この関数を使用して(サーバーインスタンスを起動する前に)grpc.Server インスタンスに登録できます。
単項メソッド
これらのメソッドは、生成されたサービスインターフェースで次のシグネチャを持ちます。
Foo(context.Context, *MsgA) (*MsgB, error)
このコンテキストでは、MsgA はクライアントから送信される protobuf メッセージであり、MsgB はサーバーから返される protobuf メッセージです。
サーバーサイドストリーミングメソッド
これらのメソッドは、生成されたサービスインターフェースで次のシグネチャを持ちます。
Foo(MsgA, <ServiceName>_FooServer) error
このコンテキストでは、MsgA はクライアントからの単一のリクエストであり、<ServiceName>_FooServer パラメータは MsgB メッセージのサーバーからクライアントへのストリームを表します。
<ServiceName>_FooServer は、grpc.ServerStream を埋め込み、次のインターフェースを持っています。
type <ServiceName>_FooServer interface {
Send(*MsgB) error
grpc.ServerStream
}
サーバー側ハンドラは、このパラメータの Send メソッドを通じてクライアントに protobuf メッセージのストリームを送信できます。サーバーからクライアントへのストリームのストリーム終了は、ハンドラメソッドの return によって引き起こされます。
クライアントサイドストリーミングメソッド
これらのメソッドは、生成されたサービスインターフェースで次のシグネチャを持ちます。
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) を返します。サーバーからの単一の応答メッセージは、この <ServiceName>_FooServer パラメータの SendAndClose メソッドを呼び出すことで送信されます。SendAndClose は 1 回だけ呼び出す必要があります。
双方向ストリーミングメソッド
これらのメソッドは、生成されたサービスインターフェースで次のシグネチャを持ちます。
Foo(<ServiceName>_FooServer) error
このコンテキストでは、<ServiceName>_FooServer は、クライアントからサーバーへのメッセージストリームとサーバーからクライアントへのメッセージストリームの両方にアクセスするために使用できます。<ServiceName>_FooServer は grpc.ServerStream を埋め込み、次のインターフェースを持っています。
type <ServiceName>_FooServer interface {
Send(*MsgA) error
Recv() (*MsgB, error)
grpc.ServerStream
}
サーバー側ハンドラは、このパラメータの Recv を繰り返し呼び出すことで、クライアントからサーバーへのメッセージストリームを読み取ることができます。Recv は、クライアントからサーバーへのストリームの終わりに達すると (nil, io.EOF) を返します。サーバーからクライアントへの応答メッセージストリームは、この <ServiceName>_FooServer パラメータの Send メソッドを繰り返し呼び出すことで送信されます。サーバーからクライアントへのストリームのストリーム終了は、バイディレクショナルメソッドハンドラの return によって示されます。
生成されたクライアントインターフェース上のメソッド
クライアント側の使用では、.proto ファイル内の各 service Bar は、次の関数も生成します。func BarClient(cc *grpc.ClientConn) BarClient。これは、BarClient インターフェースの具象実装を返します(この具象実装も生成された .pb.go ファイルにあります)。
単項メソッド
これらのメソッドは、生成されたクライアントスタブで次のシグネチャを持ちます。
(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (*MsgB, error)
このコンテキストでは、MsgA はクライアントからサーバーへの単一のリクエストであり、MsgB はサーバーから返された応答を含みます。
サーバーサイドストリーミングメソッド
これらのメソッドは、生成されたクライアントスタブで次のシグネチャを持ちます。
Foo(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
このコンテキストでは、<ServiceName>_FooClient は MsgB メッセージのサーバーからクライアントへの stream を表します。
このストリームは grpc.ClientStream を埋め込み、次のインターフェースを持っています。
type <ServiceName>_FooClient interface {
Recv() (*MsgB, error)
grpc.ClientStream
}
ストリームは、クライアントがスタブで Foo メソッドを呼び出したときに開始されます。その後、クライアントは返された <ServiceName>_FooClient ストリームの Recv メソッドを繰り返し呼び出して、サーバーからクライアントへの応答ストリームを読み取ることができます。この Recv メソッドは、サーバーからクライアントへのストリームが完全に読み取られたときに (nil, io.EOF) を返します。
クライアントサイドストリーミングメソッド
これらのメソッドは、生成されたクライアントスタブで次のシグネチャを持ちます。
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
このコンテキストでは、<ServiceName>_FooClient は MsgA メッセージのクライアントからサーバーへの stream を表します。
<ServiceName>_FooClient は grpc.ClientStream を埋め込み、次のインターフェースを持っています。
type <ServiceName>_FooClient interface {
Send(*MsgA) error
CloseAndRecv() (*MsgB, error)
grpc.ClientStream
}
ストリームは、クライアントがスタブで Foo メソッドを呼び出したときに開始されます。その後、クライアントは返された <ServiceName>_FooClient ストリームの Send メソッドを繰り返し呼び出して、クライアントからサーバーへのメッセージストリームを送信できます。このストリームの CloseAndRecv メソッドは、クライアントからサーバーへのストリームを閉じ、サーバーからの単一の応答メッセージを受信するために、1 回だけ呼び出す必要があります。
双方向ストリーミングメソッド
これらのメソッドは、生成されたクライアントスタブで次のシグネチャを持ちます。
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
このコンテキストでは、<ServiceName>_FooClient は、クライアントからサーバーへのメッセージストリームとサーバーからクライアントへのメッセージストリームの両方を表します。
<ServiceName>_FooClient は grpc.ClientStream を埋め込み、次のインターフェースを持っています。
type <ServiceName>_FooClient interface {
Send(*MsgA) error
Recv() (*MsgB, error)
grpc.ClientStream
}
ストリームは、クライアントがスタブで Foo メソッドを呼び出したときに開始されます。その後、クライアントは返された <SericeName>_FooClient ストリームの Send メソッドを繰り返し呼び出して、クライアントからサーバーへのメッセージストリームを送信できます。クライアントはまた、このストリームの Recv を繰り返し呼び出して、サーバーからクライアントへのメッセージストリーム全体を受信することもできます。
サーバーからクライアントへのストリームのストリーム終了は、ストリームの Recv メソッドで (nil, io.EOF) を返すことによって示されます。クライアントからサーバーへのストリームのストリーム終了は、クライアント側でストリームの CloseSend メソッドを呼び出すことで示される場合があります。
パッケージと名前空間
protoc コンパイラが --go_out=plugins=grpc: で呼び出された場合、protoパッケージから Go パッケージへの翻訳は、protoc-gen-go プラグインを grpc プラグインなしで使用した場合と同じように機能します。
たとえば、foo.proto が package foo であると宣言している場合、生成される foo.pb.go ファイルも Go の package foo になります。