之前我们上一章实现了gRPC的数据传递的第一种形式;

第一种形式:客户端向服务端发送请求,服务端返回给客户端响应

第二种形式:客户端向服务端发送流式请求(stream),服务端向客户端返回响应

第三种形式:客户端向服务端发送请求,服务端向客户端返回流式响应(stream)

第四种形式:客户端向服务端发送流式请求(stream),服务端向客户端返回流式响应(stream)

 

在gRPC的编程中,我们可以发现对于服务端的控制基本上不需要做任何的操作。

grpc 和 netty grpc和netty的关系_grpc 和 netty

主要需要修改的地方是服务处理对象StudentServerImpl

grpc 和 netty grpc和netty的关系_grpc 和 netty_02

以上描述的就是我们后面将要实现的三种方法的整体逻辑。

现在修改.proto文件

修改内容:请求参数是int类型,响应参数是流式StudentResponse类型

grpc 和 netty grpc和netty的关系_gRPC服务器流式调用实现_03

在编译的时候出错,出错信息说的是目录不存在,但是其实它不是主要问题,主要问题是下面那个提示:

Expected message type

grpc 和 netty grpc和netty的关系_grpc 和 netty_04

 问题就在于gRPC请求信息和响应信息必须是message类型,gRPC不同于.thrift数据,在之前我们使用Thrift的时候,对于方法体我们是可以传入string类型的。即使message里面只有一个字段或者一个类型,在使用gRPC的时候也必须是message类型。

修改之后:

grpc 和 netty grpc和netty的关系_客户端_05

在这里我又要多说一点,那就是为什么StudentRequest中age=1,在StudentResponse中name=1,age=2,city=3;

首先他们是在同一个rpc方法中相互对应的,那么请求里面的age与响应里面的age是相互对应的,这样的话他们两个是不一样的,为了区分请求中的设置为1,而响应中的设置为2。现在大概能够理解了吧。至于为什么要这么做,这是gRPC的规范,没有为什么!

我们继续执行编译

grpc 和 netty grpc和netty的关系_grpc 和 netty_06

 

grpc 和 netty grpc和netty的关系_grpc 和 netty_07

 copy到项目包下:

grpc 和 netty grpc和netty的关系_服务端_08

这里解释一下什么叫做流式(stream),也前面这个例子来讲解,我们从客户端发送请求给服务端。然后从服务端响应一个集合给客户端。这个集合就是流(stream)。

现在增加服务处理对象的方法,看到这个的话,对于上面的理解应该能够清晰了。+

grpc 和 netty grpc和netty的关系_客户端_09

 客户端代码

grpc 和 netty grpc和netty的关系_服务端_10

我们从服务端发送响应到客户端,对于这个流程来说我们很好理解,但是客户端client是以怎样的形式来接收服务端传递过来的响应的呢?

 通过查看getStudentsByAge()源码就会发现,该方法返回的是迭代器对象

grpc 和 netty grpc和netty的关系_gRPC服务器流式调用实现_11

依次打印 迭代器中的对象: 

grpc 和 netty grpc和netty的关系_gRPC服务器流式调用实现_12

启动服务器:

grpc 和 netty grpc和netty的关系_客户端_13

启动客户端:

grpc 和 netty grpc和netty的关系_Netty的深入浅出_14

grpc 和 netty grpc和netty的关系_客户端_15

现在我们考虑另外一种 :

客户端向服务端发送流式请求信息,这时候服务端就向客户端返回集合

proto文件加入代码如下:

repeated :集合类型

grpc 和 netty grpc和netty的关系_Netty的深入浅出_16