Java gRPC流被取消
我正试图通过gRPC创建一个流API,但我的StreamObserver由于一些奇怪的原因被取消了。 这是我的Java gRPC流被取消,java,protocol-buffers,grpc,grpc-java,Java,Protocol Buffers,Grpc,Grpc Java,我正试图通过gRPC创建一个流API,但我的StreamObserver由于一些奇怪的原因被取消了。 这是我的.proto声明: service Service { rpc connect (ConnectionRequest) returns (stream StreamResponse) {} rpc act (stream ActRequest) returns (ActResponse) {} } 其思想是用户将连接,因此将为每个用户保存流响应,然后在每个动作上,流响
.proto
声明:
service Service {
rpc connect (ConnectionRequest) returns (stream StreamResponse) {}
rpc act (stream ActRequest) returns (ActResponse) {}
}
其思想是用户将连接
,因此将为每个用户保存流响应
,然后在每个动作
上,流响应
将接收更新。下面是服务的java实现
class ServiceImpl extends ServiceGrpc.ServiceImplBase {
............
@Override
public void connect(ConnectionRequest request, StreamObserver<StreamResponse> responseObserver) {
observers.add(responseObserver);
}
@Override
public StreamObserver<ActRequest> act(StreamObserver<ActResponse> responseObserver) {
return return new StreamObserver<ActRequest>() {
@Override
public void onNext(ActRequest actRequest) {
StreamResponse streamResponse = StreamResponse.newBuilder().build();
observers.forEach(o -> o.onNext(streamResponse));
actRequest..onCompleted();
}
...............
};
}
..................
}
客户act
方法:
ServiceGrpc.ServiceStub stub = ServiceGrpc.newStub(channel);
new StreamObserver<PlayerResponse>() {
........
@Override
public void onNext(StreamResponse streamResponse) {
logger.info("Act: " streamResponse.getData());
}
........
}
ConnectionRequest request = ConnectionRequest.newBuilder().build();
stub.connect(request, streamObserver);
StreamObserver<ActResponse> observer = new StreamObserver<ActResponse>() {
@Override
public void onNext(ActResponse actResponse) {
logger.info("Status: " + actResponse.getSuccess());
}
.........
};
StreamObserver<ActRequest> act = stub.act(observer);
act.onNext(MoveRequest.newBuilder().build());
act.onCompleted();
在调试模式下,我可以看到StreamObserver responseObserver
是cancelled=true
我找到了产生此错误的原因。在客户端中,我使用Vaadin
构建UI。因此,在StreamObserver#onNext
上,我调用了一个Vaadin方法,该方法会抛出一个异常
我在开发过程中犯的错误是,我将onError
留空,因为它是一个PoC。但是这个错误花费了我几个小时的调试。
这是一个愚蠢的错误,但我会让它留在这里,也许它可以为某人节省一些时间。您确定要调用actRequest..onCompleted()在服务器的onNext()
方法中的code>?“看来那里出了点问题。”我想是的。actRequest
不是一个动作流,它只是您正在调用的一个事件.onCompleted()
不确定要调用哪个对象。然后,当下一个客户端调用到来时,您将调用o.onNext(streamResponse)
。感觉这就是问题所在。@Ran我不是为StreamResponse
调用onCompleted
,只是为ActRequest
和ActResponse
调用。但取消后将成为StreamObserver
。我甚至尝试不为这两个对象调用onCompleted
,但结果是相同的act.onCompleted()客户机代码中的code>。也许这是在关闭连接。
io.grpc.StatusRuntimeException: CANCELLED: call already cancelled
at io.grpc.Status.asRuntimeException(Status.java:517)
at io.grpc.stub.ServerCalls$ServerCallStreamObserverImpl.onNext(ServerCalls.java:335)