- gRPC允许定义四类服务方法
- 流是会结束的
- stream(流式传输)编写流程
- 客户端使用
ClientReader
- 客户端使用
ClientWriter
- 客户端使用
ClientReaderWriter
- 服务器端
gRPC允许定义四类服务方法
-
一元RPC:客户端发送一次请求,等待服务端响应结构,会话结束,就像一次普通的函数调用这样简单
-
服务端流式RPC:客户端发起一起请求,服务端会返回一个流,客户端会从流中读取一系列消息,直到没有结果为止
-
客户端流式RPC:客户端提供一个数据流并写入消息发给服务端,一旦客户端发送完毕,就等待服务器读取这些消息并返回应答
-
双向流式RPC:客户端和服务端都提供一个数据流,都可以通过各自的流进行读写数据,这两个流是相互独立的,客户端和服务端都可以按其希望的任意顺序独写
原文链接:https://blog.csdn.net/jianfeng123123/article/details/128110603
流是会结束的
并不似长连接,建立上之后就一直保持,有消息的时候发送。(是否有通过建立一个流 RPC 建立推送机制?)
Client 发送流,是通过 Writer->WritesDone() 函数结束流
Server 发送流,是通过结束 RPC 函数并返回状态码的方式来结束流
流接受者,都是通过 Reader->Read() 返回的 bool 型状态,来判断流是否结束
Server 并没有像 Client 一样调用 WriteDone(),而是在消息之后,将 status code、可选的 status message、可选的 trailing metadata 追加进行发送,这就意味着流结束了。
xxx.pb.h
和xxx.pb.cc
: 生成我们编写的proto message数据结构类型的相关的方法,这两个文件是对proto文件中各消息结构的方法的创建和实现,清除,设置,获取等
xxx.grpc.pb.cc
和xxx.grpc.pb.h
:生成proto文件中rpc函数客户端和服务器的相关方法,用于grpc服务器,客户端通讯相关的方法
stream(流式传输)编写流程
grpc的流式传输的有三种类: grpc::ClientReader; grpc::ClientWriter; grpc::ClientReaderWriter;
grpc::ClientReaderWriter类是输入输出都是流的函数类,例如代码中的Stream函数。
他们三个类基本方法都一样
- ClientReaderWriter类中包含Read Write两个方法,可读可写
- 而ClientReader类中包含Read方法,只可读
- ClientWriter类中包含Write方法,只可写。
WritesDone方法(流数据写结束标识):ClientReaderWriter,ClientWriter都包含该方法。
Finish方法(读流数据结束标识):ClientReaderWriter,ClientReader都包含该方法。
三种类中的方法用法一样,grpc::ClientReader; grpc::ClientWriter不再做单独说明,用法和grpc::ClientReaderWriter一样。
使用哪个类就加上对应的命名空间的使用声明
-
服务器:
- using grpc::ServerReader;
- using grpc::ServerWriter;
- using grpc::ServerReaderWriter;
- 服务器没有客户端的WritesDone()和 Finish()方法,用法参考代码,Read() Write()方法的使用和客户端是一样的。
-
客户端:
- using grpc::ClientReader;
- using grpc::ClientWriter;
- using grpc::ClientReaderWriter;
在gRPC中,流式传输(Streaming)是一种允许在单个RPC调用中发送多个消息序列的功能。这对于需要处理大量数据或需要实时交互的应用非常有用。以下是一个简化的流程,说明如何在gRPC中使用ClientReader
, ClientWriter
, 和 ClientReaderWriter
类进行流式传输的编写。
客户端使用 ClientReader
-
创建Stub:首先,你需要有一个gRPC服务的stub实例。
-
调用流式方法:通过stub调用服务定义中声明的流式方法,这将返回一个
ClientReader
对象。 -
读取数据:在循环中调用
ClientReader
的Read
方法,该方法将尝试从服务器读取下一个消息。如果返回true
,则消息已填充到传入的参数中;如果返回false
,则表示没有更多消息可读(可能是因为流已关闭或发生错误)。 -
处理读取到的数据:在循环内部,处理从服务器接收到的每个消息。
-
完成读取:一旦
Read
方法返回false
,通常意味着流已结束。此时,可以调用Finish
方法来获取RPC调用的最终状态(成功或失败)。
客户端使用 ClientWriter
-
创建Stub:同样,首先需要gRPC服务的stub实例。
-
调用流式方法:通过stub调用服务定义中声明的流式方法,这将返回一个
ClientWriter
对象。 -
写入数据:在循环中调用
ClientWriter
的Write
方法,将消息发送到服务器。继续发送消息直到所有数据都已发送。 -
标记写入完成:使用
WritesDone
方法标记所有消息都已发送完毕。这允许服务器知道不会再有更多的消息被发送,并开始处理已接收的消息。 -
完成写入:调用
Finish
方法等待服务器处理完所有消息并返回RPC调用的最终状态。
客户端使用 ClientReaderWriter
-
创建Stub:与前两者相同,首先需要gRPC服务的stub实例。
-
调用流式方法:通过stub调用服务定义中声明的双向流式方法,这将返回一个
ClientReaderWriter
对象。 -
读写数据:在需要时,可以在循环中交替调用
Write
方法和Read
方法。发送消息到服务器并读取来自服务器的响应。 -
标记写入完成:当所有消息都已发送时,使用
WritesDone
方法标记写入完成。 -
完成读写:继续读取服务器的响应直到
Read
方法返回false
,然后调用Finish
方法等待RPC调用的最终状态。
服务器端
服务器端处理流式RPC的方式与客户端略有不同,但基本概念相同。服务器端使用ServerReader
, ServerWriter
, 或 ServerReaderWriter
来接收或发送消息。服务器端的实现需要处理这些流对象提供的读写操作,并在适当的时候返回RPC调用的结果。
请注意,实际实现细节(如错误处理、流控制等)可能会根据具体的应用场景和需求而有所不同。