首页 > 解决方案 > 有人可以向我解释 gRPC StreamObserver.onError 的正确用法是什么吗?

问题描述

我正在尝试正确处理 gRPC 错误(Java、Spring-boot 应用程序)。

基本上,我也需要将错误详细信息从 gRPC 服务器传输到客户端,但我发现很难理解StreamObserver.onError();

方法文档说:

“从流中接收到一个终止错误。只能调用一次,如果被调用,它必须是最后一个调用的方法。特别是如果 onError 的实现抛出异常,则不允许进一步调用任何方法。”

这个“不允许再打电话”是什么意思?根据文档,在我维护的应用程序中,他们调用其他 gRPC 方法并且他们得到java.lang.IllegalStateException: call already closed了很好的方法。

我想知道 - 我(开发人员)是否应该在收到错误后终止当前的 java 方法(使用 gRPC 调用)?例如抛出异常以停止执行。或者预计 gRPC 将终止执行..(类似于从 gRPC 抛出异常)

基本上我该如何正确使用onError(),如果我调用它,我应该期待和处理什么?我需要解释它的用法和效果。

标签: error-handlinggrpc-java

解决方案


涉及两个StreamObserver实例。一种用于入站方向,即您实现并传递给 gRPC 库的StreamObserver实例。这是包含如何处理响应的逻辑。另一个是outbound方向,即gRPC库调用RPC方法时返回给你的实例。这是您用来发送请求的。大多数时候,这两个是相互交互的(例如,在一个全双工的流式调用中,响应通常会调用 request的方法,这就是你实现乒乓行为的方式)。StreamObserverStreamObserverStreamObserverStreamObserverStreamObserverStreamObserveronNext()

“不允许进一步调用”意味着当调用 inbound的方法时onNext(),您不应再调用onComplete()和/或onError() 在出站方向上StreamObserver调用,即使您的入站实现抛出异常也是如此。由于入站是异步调用的,因此它与包含's 实现的方法无关。StreamObserveronError()onError()StreamObserverStreamObserver

例如:


public class HelloWorld {
  private final HelloWorldStub stub;
  private StreamObserver<HelloRequest> requestObserver;

  ...

  private void sendRequest(String message) {
    requestObserver.onNext(HelloRequest.newBuilder.setMessage(message).build());
  }

  public void start() {
    stub.helloWorld(new StreamObserver<HelloResponse> {
      @Override
      public void onNext(HelloResponse response) {
        sendRequest("hello from client");
        // Optionally you can call onCompleted() or onError() on 
        // the requestObserver to terminate the call.
      }

      @Override
      public void onCompleted() {
        // You should not call any method on requestObserver.
      }

      @Override
      public void onError(Throwable error) {
        // You should not call any method on requestObserver.
      }
    });
  }

}

它与方法无关start()

该文档还提到您不应该做类似的事情

try {
  requestObserver.onCompleted();
} catch(RuntimeException e) {
  requestObserver.onError();
}

它主要用于用户自己的StreamObserver实现。StreamObserver由 gRPC 返回的永远不会抛出。


推荐阅读