【问题标题】:io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method not foundio.grpc.StatusRuntimeException:未实现:找不到方法
【发布时间】:2019-05-18 03:27:55
【问题描述】:

使用 Springboot 启动应用程序。一切正常。然后我将客户端和服务器移动到新包中。一切都可以编译,但是在运行时运行客户端时出现错误:未找到未实现的方法。

我检查了该方法实际上已实现。当我启动 Springboot 应用程序时,我在哪里确认 bean 本身已加载?我只看到确认应用程序已启动并正在运行,但日志中没有加载的 bean 列表。

这是我的 Springboot 应用程序。我所做的只是将客户端和服务器 bean 移动到一个名为 example.client 和 example.server 的新包中。在它们与 Spring Boot com.test.MyApplication 位于同一包之前

io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method not found:  example.GreetingService/greetingWithResponseStream
at io.grpc.Status.asRuntimeException(Status.java:526)
at  io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:434)
at  io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)



package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
}
}

GreetingService.proto:

syntax = "proto3";
package example;

message HelloRequest {
    string name = 1;
}


message HelloResponse {
    string greeting = 1;
}


service GreetingService {
    rpc greeting (HelloRequest) returns (HelloResponse);
    rpc greetingWithResponseStream (HelloRequest) returns (stream  HelloResponse);
  rpc greetingWithRequestStream (stream HelloRequest) returns  (HelloResponse);
rpc greetingWithRequestResponseStream (stream HelloRequest) returns  (stream HelloResponse);

}

import example.GreetingServiceOuterClass;

import io.grpc.stub.StreamObserver;
import java.util.ArrayList;
import java.util.List;

@GrpcService
public class GreetingServiceImpl extends    GreetingServiceGrpc.GreetingServiceImplBase{

@Override
public void greeting(GreetingServiceOuterClass.HelloRequest request,   StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
    GreetingServiceOuterClass.HelloResponse response =    GreetingServiceOuterClass.HelloResponse.newBuilder()
            .setGreeting("HELLO, THERE, " + request.getName())
            .build();
    responseObserver.onNext(response);
    responseObserver.onCompleted();

}

@Override
public void  greetingWithResponseStream(GreetingServiceOuterClass.HelloRequest request, StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
    GreetingServiceOuterClass.HelloResponse response =  GreetingServiceOuterClass.HelloResponse.newBuilder()
            .setGreeting("(Stream Response) Hello there, " + request.getName())
            .build();
    responseObserver.onNext(response);
    responseObserver.onNext(response);
    responseObserver.onNext(response);
    responseObserver.onCompleted();
}

@Override
public StreamObserver<GreetingServiceOuterClass.HelloRequest>  greetingWithRequestStream(StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
    return new StreamObserver<GreetingServiceOuterClass.HelloRequest>() {
        private List<String> nameList = new ArrayList<>();

        @Override
        public void onNext(GreetingServiceOuterClass.HelloRequest request) {
            nameList.add(request.getName());
        }

        @Override
        public void onError(Throwable t) {
            t.printStackTrace();
        }

        @Override
        public void onCompleted() {
            GreetingServiceOuterClass.HelloResponse response = GreetingServiceOuterClass.HelloResponse.newBuilder()
                    .setGreeting("(Stream Request) Hello there, " + String.join(" ", nameList))
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        }
    };
}

@Override
public StreamObserver<GreetingServiceOuterClass.HelloRequest> greetingWithRequestResponseStream(StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
    return new StreamObserver<GreetingServiceOuterClass.HelloRequest>() {
        private List<String> nameList = new ArrayList<>();

        @Override
        public void onNext(GreetingServiceOuterClass.HelloRequest request) {
            nameList.add(request.getName());
        }

        @Override
        public void onError(Throwable t) {
            t.printStackTrace();
        }

        @Override
        public void onCompleted() {
            nameList.stream()
                    .map(name ->  GreetingServiceOuterClass.HelloResponse.newBuilder().setGreeting("(Stream Request/Response) Hello there, " + name).build())
                    .forEach(responseObserver::onNext);
            responseObserver.onCompleted();
        }
    };
}
}


package example.client;

import example.GreetingServiceGrpc;
import example.GreetingServiceOuterClass;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;

import java.util.stream.Stream;

public class Client {
public static void main(String[] args) {
    ManagedChannel channel =   ManagedChannelBuilder.forTarget("localhost:8081")
            .usePlaintext()
            .build();

        GreetingServiceGrpc.GreetingServiceBlockingStub stub =    GreetingServiceGrpc.newBlockingStub(channel);
    GreetingServiceOuterClass.HelloRequest request = GreetingServiceOuterClass.HelloRequest.newBuilder().setName("Steve").build();
    GreetingServiceOuterClass.HelloResponse response = stub.greeting(request);
    System.out.println(response);
}


public static class RequestStreamClient {


    public static void main(String[] args) throws InterruptedException  {

        new Thread(() -> {

            ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8081")
                    .usePlaintext()
                    .build();

            GreetingServiceGrpc.GreetingServiceStub stub = GreetingServiceGrpc.newStub(channel);

            StreamObserver<GreetingServiceOuterClass.HelloRequest> requestStream =
                    stub.greetingWithRequestStream(new StreamObserver<GreetingServiceOuterClass.HelloResponse>() {
                        @Override
                        public void onNext(GreetingServiceOuterClass.HelloResponse response) {
                            System.out.println(response);
                        }

                        @Override
                        public void onError(Throwable t) {
                            t.printStackTrace();
                        }

                        @Override
                        public void onCompleted() {
                        }
                    });

            Stream.of("Steve1", "Steve2", "Steve3")
                    .map(name -> GreetingServiceOuterClass.HelloRequest.newBuilder().setName(name).build())
                    .forEach(requestStream::onNext);
            requestStream.onCompleted();



        }).start();

        Thread.sleep(10000);


    }

  }
}

【问题讨论】:

    标签: java spring spring-boot grpc grpc-java


    【解决方案1】:

    @SpringBootApplication javadoc 状态:

    这是一个方便的注解,相当于声明 @Configuration、@EnableAutoConfiguration 和@ComponentScan。

    而@ComponentScan javadoc 声明:

    如果没有定义特定的包,扫描将从 声明此注解的类的包。

    这意味着默认情况下,@SpringBootApplication 注解会扫描同一包或以下的所有类(请参阅the best practices,了解如何在 Spring Boot 应用程序中构建代码)。

    但是如果你不想移动你的类,你可以显式地导入它们,使用主类上的@ComponentScan 或@Import 注解:

    @SpringBootApplication
    @ComponentScan({"example.client","example.server"})
    @Import(GreetingServiceImpl.class)
    public class MyApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-06
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      相关资源
      最近更新 更多