gRPC从0到1系列【11】
文章目录
- 五、客户端流式RPC (Client Streaming RPC)
- 5.1 概述
- 5.1.1 什么是客户端流式rpc?
- 5.1.2 为什么需要客户端流式 RPC?
- 5.1.3 工作原理与 StreamObserver角色
- 5.1.4 流程简图
五、客户端流式RPC (Client Streaming RPC)
5.1 概述
5.1.1 什么是客户端流式rpc?
客户端流式 RPC 是 gRPC 支持的四种通信模式之一。在这种模式下:
- 客户端:可以连续不断地向服务端发送多个请求消息,形成一个数据流(Stream)。
- 服务端:在接收到客户端的所有请求消息后,才会处理并返回一个响应消息。
你可以把它想象成:你(客户端)在一个餐厅里,不是一次性点完所有菜,而是想起来一道就告诉服务员(发送一个请求),想起来另一道再告诉服务员。当你确认所有菜都点完了(客户端流结束),服务员才会把你的点菜单交给厨房。厨房做好所有菜后,一次性端上来(返回一个响应)。
5.1.2 为什么需要客户端流式 RPC?
客户端流式 RPC 特别适用于以下场景:
- 数据收集与汇总:客户端需要将一批数据发送给服务端进行聚合、分析或计算。例如:
- 发送多个传感器的读数,服务端计算平均值或总和。
- 上传一个大文件,将其切分成多个小块流式上传,服务端在接收完整后进行校验或存储。
- 收集用户的一系列操作日志,服务端进行批量处理和分析。
- 实时数据处理的 “结束 - 触发” 模式:客户端持续发送实时数据,但服务端的处理逻辑需要在客户端明确表示 “数据发送完毕” 后才执行。例如:
- 客户端发送一系列坐标点,服务端在接收完所有点后,计算出最佳路径并返回。
- 客户端发送多个文档片段,服务端在接收完整后进行全文索引或翻译。
优势:
- 减少延迟:客户端无需等待所有数据都准备好才开始发送,可以边产生数据边发送,降低了总的处理时间。
- 内存效率:对于非常大的数据集或文件,客户端可以分块发送,避免了在内存中构建巨大的请求对象。
- 灵活性:提供了一种 “先收集,后处理” 的异步通信范式。
5.1.3 工作原理与 StreamObserver角色
✅ 1. 通信流程
🆕 StreamObserver角色分析
-
客户端 (Client):
- requestObserver: 客户端调用 RPC 方法后,gRPC 框架立即返回一个
StreamObserver
。客户端通过调用这个 requestObserver的onNext()
方法来发送流式请求数据。 - responseObserver: 客户端在发起 RPC 调用时,需要自己实现并传入一个
StreamObserver
。这个 responseObserver用于接收服务端最终返回的那一个响应消息(通过onNext()
)以及 RPC 的完成或错误通知(通过 onCompleted() 或onError()
)。
- requestObserver: 客户端调用 RPC 方法后,gRPC 框架立即返回一个
-
服务端 (Server):
-
requestObserver(隐式实现): 服务端需要实现 gRPC 生成的服务接口。
-
在客户端流式方法中,服务端的实现会接收一个 StreamObserver 作为参数。这个
StreamObserver
正是服务端用来 “观察” 客户端发送过来的流式请求的。服务端通过重写这个 StreamObserver 的onNext()
、onError()
和onCompleted()
方法来处理客户端的数据流。- onNext(): 每次客户端调用 requestObserver.onNext(),服务端的这个
onNext()
就会被调用,服务端可以在这里累加或处理数据。 onCompleted()
: 当客户端调用 requestObserver.onCompleted()后,服务端的这个onCompleted()
会被调用。这是服务端开始执行最终计算或处理逻辑的信号。
- onNext(): 每次客户端调用 requestObserver.onNext(),服务端的这个
-
responseObserver(框架提供): 服务端的方法实现需要返回一个 StreamObserver。这个 StreamObserver 由 gRPC 框架提供,服务端通过调用它的
onNext()
方法来发送最终的响应,并调用onCompleted()
来结束整个 RPC。