记录一下,怕忘了,参考意义不大。
有问题可纠正。
看官方demo的时候,发现在proto文件(route_guide.proto)中,示例定义了4类rpc方法,分别是
rpc GetFeature(Point) returns (Feature) {}
rpc ListFeatures(Rectangle) returns (stream Feature) {}
rpc RecordRoute(stream Point) returns (RouteSummary) {}
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
如图所示
其对应了gRPC的四种请求响应模式,分别是
UNARY(简单模式),
SERVER_STREAMING(服务端流模式),
CLIENT_STREAMING(客户端流模式),
BIDI_STREAMING(双向流模式)
可以在io.grpc.MethodDescriptor.MethodType中找到相关定义
在实际使用中,使用proto文件通过编译工具生成grpc代码后,常常见到这种代码(对应上文proto文件中定义的4类rpc方法)
package com.fsyy.demo.test;
import io.grpc.examples.routeguide.*;
import io.grpc.stub.StreamObserver;
public class RouteGuideService extends RouteGuideGrpc.RouteGuideImplBase {
@Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
}
@Override
public void listFeatures(Rectangle request, StreamObserver<Feature> responseObserver) {
}
@Override
public StreamObserver<Point> recordRoute(StreamObserver<RouteSummary> responseObserver) {
return null;
}
@Override
public StreamObserver<RouteNote> routeChat(StreamObserver<RouteNote> responseObserver) {
return null;
}
}
发现前两个方法比较相似,后两个方法比较相似,并不能对比出rpc定义中stream关键字的作用,是否说明stream关键字跟在return的参数后没什么作用。其实不然,检查生成的RouteGuideGrpc.java代码中,发现有这么一段。
虽然方法长得差不多,但最后通过ClientCalls进行调用时,还是有区分的,构造的是不同类型的调用客户端。
为了弄清楚这几种模式的区别,咱继续看官方demo代码,在其RouteGuideServer.java即服务端代码中,实现了getFeature方法,是当收到客户端Point请求时,返回Feature类型的响应。我在想,既然逻辑是自己实现,为什么我只发一次响应呢,我能不能多发,发响应流。说做就做,我在示例代码调用onCompleted方法前又加了一条一模一样的onNext语句。执行后,发现控制台有一条waring语句,显示"Too many response"。
定位到代码ServerCallImpl.java,在sendMessageInternal方法中,有一个if判断。
if (this.method.getType().serverSendsOneMessage() && this.messageSent)
这里就会判断你的client调用method类型和是否已经发送过消息。通过此处限定,可了解到对于UNARY模式和CLIENT_STREAMING模式,只能发一个响应。而另外两种模式,则能发送Stream响应,可简单理解为多个响应。
省略……
所以,UNARY模式就是一个请求然后返回一个响应,如果你一个
UNARY可简单理解为一个请求一个响应完成后才能进行下个请求响应;
SERVER_STREAMING可简单理解为一个客户端请求多个服务端响应,
CLIENT_STREAMING可简单理解为多个客户端请求一个服务端响应,
BIDI_STREAMING可简单理解为多个客户端请求多个服务端响应。
其它,可以看看ServerCalls.java和ClientCalls.java代码,ClientCalls.java中有个hasNext()方法,里面有个wait等待,已确保流式响应为完成前,客户端调用相关的hasNext()方法时会一直等待响应发送(当服务端执行一次onNext时,客户端会唤醒等待)。
哈班,不想写和调整了!