当前位置: 首页 > 知识库问答 >
问题:

在服务器上调用onNext时,gRPC“呼叫已关闭”异常

林星华
2023-03-14

不幸的是,这种情况在生产中偶尔发生,但我无法可靠地复制。

gRPC服务器向少数客户端发送小而频繁的更新。每个客户端使用不同的参数对同一个调用发出多个请求。永远不会有来自服务器的数据流。

调用onNext时,出现以下错误:

Feb 20, 2019 10:13:03 AM io.grpc.internal.SerializingExecutor run
SEVERE: Exception while executing runnable concord.grpc.UncaughtExceptionServerInterceptor$SerializingServerCall$$Lambda$47/1901113624@2b4ca8e3
java.lang.IllegalStateException: call is closed
at com.google.common.base.Preconditions.checkState(Preconditions.java:174)
at io.grpc.internal.ServerCallImpl.sendMessage(ServerCallImpl.java:124)
at io.grpc.ForwardingServerCall.sendMessage(ForwardingServerCall.java:32)
at concord.grpc.UncaughtExceptionServerInterceptor$SerializingServerCall.access$1001(UncaughtExceptionServerInterceptor.java:142)
at concord.grpc.UncaughtExceptionServerInterceptor$SerializingServerCall.lambda$sendMessage$0(UncaughtExceptionServerInterceptor.java:158)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:456)
at io.grpc.internal.SerializingExecutor.schedule(SerializingExecutor.java:93)
at io.grpc.internal.SerializingExecutor.execute(SerializingExecutor.java:86)
at concord.grpc.UncaughtExceptionServerInterceptor$SerializingServerCall.sendMessage(UncaughtExceptionServerInterceptor.java:158)
at io.grpc.stub.ServerCalls$ServerCallStreamObserverImpl.onNext(ServerCalls.java:341)
at myPackage$helper.lambda$calculateChangesAndNotifyObservers$1(myCode.java:229)

根据gRPC订阅数据的请求,保留观察员名单。多个客户端可能会请求完全相同的更新,因此每个进入的客户端都会被添加到相应数据的列表中。

如果他们取消,他们将通过以下方式从列表中删除:

if( responseObserver instanceof ServerCallStreamObserver<?> )
{
    ((ServerCallStreamObserver<?>) responseObserver).setOnCancelHandler( () ->
    {
        synchronized( _lastSnapshot )
        {
            _observers.remove( responseObserver );
        }                       
    } );
}

捕捉从onNext抛出的异常并简单地从列表中删除客户端是否明智?还是有更好的检测方法?还是我需要解决一个潜在的问题?

共有1个答案

慕容安易
2023-03-14

我今天也犯了这个错误。因为我在调用build()后更改了生成器值。错误:

SyncAepUserResponse.Builder builder = SyncAepUserResponse.newBuilder();
builder.setStatus(Status.newBuilder().setCode(200).setMessage("Successful"))
                    .setMapId(entity.getId()).build();
builder.setCode("200");
responseObserver.onNext(response);
responseObserver.onCompleted();

正确的:

SyncAepUserResponse.Builder builder = SyncAepUserResponse.newBuilder();
builder.setCode("200");
builder.setStatus(Status.newBuilder().setCode(200).setMessage("Successful"))
                    .setMapId(entity.getId()).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
 类似资料:
  • 我在java应用程序中使用gRPC(非阻塞存根),两个函数调用之间的响应时间约为5-8ms。我想减少它。你有什么建议?有可能吗?

  • 这些文件来自于我的项目谁工作完美的另一个分支。 下面是我的脚本应该如何工作: 导航到“auth/login” 用户输入他的凭据 AuthService调用后端wepApi以获取承载令牌 后端返回令牌。 AuthService将他的var“is loggedin”设置为true; AuthService用于路由器导航到'/home' AuthGuard通过检查AuthService的“正在登录”来检

  • 所以我有一个。我想知道每个下游订户调用何时发出,这既是为了测量每个下游订户花费的时间,也是为了反压。 让我半途而废--我可以用自己的包装每个单独的订阅服务器,如下面的示例所示。当所有下游订户完成下一个调用时,它不会通知我,而我自己也不必做一些记账。 提前感谢!

  • 我有3个类:主要游戏,ufoMovement(实际上是一个线程)和ufo本身(是的,在图片中是德语,但他们只是名字)。UfoMovement创建了一个Ufo,它有一个叫做“爆炸”的方法,其中组件会飞离。主游戏开始线程UFOMovement。这个游戏是一个小行星躲避游戏,你的ufo正在飞行,你必须躲避小行星,这意味着我必须从main类调用方法:Explomde,因为那个类检查碰撞,但是当我调用mai

  • 编辑问题,以包括预期行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答问题。 为什么以下代码不能保证多个线程之间total_home数量的唯一性,即使逻辑位于同步块中也是如此。 } } } 这是一个程序示例。试着运行5-10次,你会发现total_home的值每次都不唯一。

  • 问题内容: 我需要在Android设备中致电Soap Web服务。我已经在其他页面上阅读了很多文章,观看了视频…但是我尝试了所有方法,但是我无法使其在我的android设备上正常工作,也无法在模拟器上进行测试,因为我的计算机无法处理其中任何一个,所以我不知道错误是否在代码上,或者这是否是我的android设备的问题。 布局xml只是一个EditText,一个Button和一个TextView。 在