Java gRPC:客户端到服务器的异常

时间:2020-06-23 07:57:51

标签: grpc grpc-java

是否可以从客户端向服务器抛出异常? 我们有一个从服务器到客户端的开放流:

rpc addStream(Request) returns (stream StreamMessage) {}     

当我尝试这样的事情时:

throw Status.INTERNAL.withDescription(e.getMessage()).withCause(e.getCause()).asRuntimeException();

我在客户端的StreamObserver.onError中获得了异常,但是在服务器端却没有异常。

1 个答案:

答案 0 :(得分:0)

服务器可以使用存根API公开为StatusRuntimeException的“状态”进行响应。但是,客户端只能“取消” RPC。服务器将不知道取消的来源;可能是因为客户端取消了,或者TCP连接断开了。

在客户端流或双向出价呼叫中,客户端可以通过调用observer.onError()(从未调用onCompleted())来取消。但是,如果名为onCompleted()的客户端或RPC有一元请求,则您需要使用ClientCallStreamObserverContext

stub.someRpc(request, new ClientResponseObserver<Request, Response>() {
  private ClientCallStreamObserver<Request> requestStream;

  @Override public void beforeStart(ClientCallStreamObserver<Request> requestStream) {
    this.requestStream = requestStream;
  }
  ...
});

// And then where you want to cancel

// RequestStream is non-thread-safe. For unary requests, wait until
// stub.someRpc() returns, since it uses the stream internally.
// The string is not sent to the server. It is just "echoed"
// back to the client's `onError()` to make clear that the
// cancellation was locally caused.
requestStream.cancel("some message for yourself", null);


// For thread-safe cancellation (e.g., for client-streaming)
CancellableContext ctx = Context.current().withCancellation();
StreamObserver requestObserver = ctx.call(() ->
  stub.someRpc(new StreamObserver<Response>() {
    @Override public void onCompleted() {
      // The ctx must be closed when done, to avoid leaks
      ctx.cancel(null);
    }

    @Override public void onError() {
      ctx.cancel(null);
    }
  }));

// The place you want to cancel
ctx.cancel(ex);