美文网首页
2023-07-07

2023-07-07

作者: xun66 | 来源:发表于2023-07-06 22:07 被阅读0次

    背景

    用Java Springboot起一个grpc服务,参照官方示例,但是启动后用Postman或者其他客户端调用时,不论调用什么方法,都是报 12 UNIMPLEMENTED。而且服务端日志里显示Stream was terminated by error, no further calls are allowed

    报错信息如下:

    2023-07-07 21:55:28.433 [grpc-default-executor-0] ERROR io.grpc.internal.SerializingExecutor- Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed@30f27e20
    java.lang.IllegalStateException: Stream was terminated by error, no further calls are allowed
        at com.google.common.base.Preconditions.checkState(Preconditions.java:511)
        at io.grpc.stub.ServerCalls$ServerCallStreamObserverImpl.onNext(ServerCalls.java:359)
        at com.example.app.report.service.grpc.ReportServiceImpl.reportCompletion(ReportServiceImpl.java:16)
        at com.example.app.report.proto.generated.ReportServiceGrpc$MethodHandlers.invoke(ReportServiceGrpc.java:312)
        at io.grpc.stub.ServerCalls$UnaryServerCallHandler$UnaryServerCallListener.onHalfClose(ServerCalls.java:182)
        at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.halfClosed(ServerCallImpl.java:331)
        at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed.runInContext(ServerImpl.java:797)
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)
    

    关键代码如下:

    public class ReportServiceImpl extends ReportServiceGrpc.ReportServiceImplBase {
        @Override
        public void report(ReportEvent request, StreamObserver<ReportResponse> responseObserver) {
            super.report(request, responseObserver);
            responseObserver.onNext(ReportResponse.newBuilder().setCode(0).build());
            responseObserver.onCompleted();
        }
    }
    

    解决过程

    在方法中打日志,这个方法确实被调用了。而且开启grpc服务端反射以后,也能读取到这个方法。
    反复和官方示例对比,最后发现IDEA自动补全的Override代码里,会自动调用super类的方法。而这个方法,默认就会返回一个Unimplemented响应。

    // 生成的reportService.java文件
    ...
        public void reportCompletion(com.example.app.report.proto.generated.CompletionEvent request,
            io.grpc.stub.StreamObserver<com.example.app.report.proto.generated.ReportResponse> responseObserver) {
          io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getReportCompletionMethod(), responseObserver); // 默认返回未实现响应
        }
    ...
    

    解决方案

    只需要把自动生成的调用super类的方法删掉即解决。

    这个错误确实没有什么资料,而且比较低级,在此记录一下。

    关键词

    Java Springboot Grpc Unimplemented

    相关文章

      网友评论

          本文标题:2023-07-07

          本文链接:https://www.haomeiwen.com/subject/nfrrudtx.html