之前我们上一章实现了gRPC的数据传递的第一种形式;
第一种形式:客户端向服务端发送请求,服务端返回给客户端响应
第二种形式:客户端向服务端发送流式请求(stream),服务端向客户端返回响应
第三种形式:客户端向服务端发送请求,服务端向客户端返回流式响应(stream)
第四种形式:客户端向服务端发送流式请求(stream),服务端向客户端返回流式响应(stream)
在gRPC的编程中,我们可以发现对于服务端的控制基本上不需要做任何的操作。
主要需要修改的地方是服务处理对象StudentServerImpl
以上描述的就是我们后面将要实现的三种方法的整体逻辑。
现在修改.proto文件
修改内容:请求参数是int类型,响应参数是流式StudentResponse类型
在编译的时候出错,出错信息说的是目录不存在,但是其实它不是主要问题,主要问题是下面那个提示:
Expected message type
问题就在于gRPC请求信息和响应信息必须是message类型,gRPC不同于.thrift数据,在之前我们使用Thrift的时候,对于方法体我们是可以传入string类型的。即使message里面只有一个字段或者一个类型,在使用gRPC的时候也必须是message类型。
修改之后:
在这里我又要多说一点,那就是为什么StudentRequest中age=1,在StudentResponse中name=1,age=2,city=3;
首先他们是在同一个rpc方法中相互对应的,那么请求里面的age与响应里面的age是相互对应的,这样的话他们两个是不一样的,为了区分请求中的设置为1,而响应中的设置为2。现在大概能够理解了吧。至于为什么要这么做,这是gRPC的规范,没有为什么!
我们继续执行编译
copy到项目包下:
这里解释一下什么叫做流式(stream),也前面这个例子来讲解,我们从客户端发送请求给服务端。然后从服务端响应一个集合给客户端。这个集合就是流(stream)。
现在增加服务处理对象的方法,看到这个的话,对于上面的理解应该能够清晰了。+
客户端代码
我们从服务端发送响应到客户端,对于这个流程来说我们很好理解,但是客户端client是以怎样的形式来接收服务端传递过来的响应的呢?
通过查看getStudentsByAge()源码就会发现,该方法返回的是迭代器对象
依次打印 迭代器中的对象:
启动服务器:
启动客户端:
现在我们考虑另外一种 :
客户端向服务端发送流式请求信息,这时候服务端就向客户端返回集合
proto文件加入代码如下:
repeated :集合类型