![](/img/trans.png)
[英]gRpc, client getting io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method even when the message is received and deserialized by the server
[英]io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method not found
使用Springboot入門應用程序。 一切正常。 然后我將客戶端和服務器移動到新的包。 所有內容都編譯,但在運行時,我運行客戶端時出現錯誤:未找到UNIMPLEMENTED方法。
我檢查了該方法實際上已實現。 當我啟動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);
}
}
}
@SpringBootApplication javadoc說明:
這是一個方便的注釋,相當於聲明@Configuration,@ EnableAutoConfiguration和@ComponentScan。
和@ComponentScan javadoc說:
如果未定義特定包,則將從聲明此批注的類的包進行掃描。
這意味着默認情況下@SpringBootApplication批注會掃描同一個包或更低版本中的所有類(請參閱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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.