Пользовательская заглушка клиента GRPC - поток не запущен - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь получить доступ к пользовательскому серверу GRPC (робот Anki Vector) по протоколу TLS из моего приложения для Android.

У меня есть файлы прототипов в моем проекте Android Studio, и все необходимые зависимости доступны.Прото-файлы генерируют классы Java, и в своей деятельности я строю канал с OkHttpChannelBuilder.Затем я создаю клиентскую заглушку (пробовал с асинхронными и блокирующими заглушками)

После этого я создаю сообщение-запрос и отправляю его с заглушкой.

Код компилируется нормально, и приложение запускается на моем компьютере.Телефон.Однако при отправке запроса я получаю сообщение об ошибке, в котором говорится, что поток не запущен.

Я не вижу способа запустить поток во всех примерах, которые я смог найти.

в чем может быть проблема, препятствующая запуску потока?

появляется сообщение об ошибке:

2019-02-10 01:08:59.303 14691-30895/com.test.anki.grpc D/vectorCTRL: Failed... : 
    java.lang.IllegalStateException: Not started
        at com.google.common.base.Preconditions.checkState(Preconditions.java:510)
        at io.grpc.internal.ClientCallImpl.request(ClientCallImpl.java:367)
        at io.grpc.PartialForwardingClientCall.request(PartialForwardingClientCall.java:34)
        at io.grpc.ForwardingClientCall.request(ForwardingClientCall.java:22)
        at io.grpc.ForwardingClientCall$SimpleForwardingClientCall.request(ForwardingClientCall.java:44)
        at io.grpc.PartialForwardingClientCall.request(PartialForwardingClientCall.java:34)
        at io.grpc.ForwardingClientCall.request(ForwardingClientCall.java:22)
        at io.grpc.ForwardingClientCall$SimpleForwardingClientCall.request(ForwardingClientCall.java:44)
        at io.grpc.PartialForwardingClientCall.request(PartialForwardingClientCall.java:34)
        at io.grpc.ForwardingClientCall.request(ForwardingClientCall.java:22)
        at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:314)
        at io.grpc.stub.ClientCalls.asyncUnaryRequestCall(ClientCalls.java:280)
        at io.grpc.stub.ClientCalls.futureUnaryCall(ClientCalls.java:189)
        at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:127)
        at Anki.Vector.external_interface.ExternalInterfaceGrpc$ExternalInterfaceBlockingStub.sayText(ExternalInterfaceGrpc.java:3554)
        at com.test.anki.grpc.MainActivity.testapi(MainActivity.java:1106)
        at com.test.anki.grpc.MainActivity$GrpcTask.doInBackground(MainActivity.java:1003)
        at com.test.anki.grpc.MainActivity$GrpcTask.doInBackground(MainActivity.java:996)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

мой код:

       ClientInterceptor clientInterceptor = new ClientInterceptor() {
            @Override
            public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> methodDescriptor, CallOptions callOptions, Channel channel) {
                // Might need to try to inject the token using that?
                return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(channel.newCall(methodDescriptor, callOptions)) {
                    @Override
                    protected void checkedStart(Listener listener, Metadata metadata) throws Exception {
                        Metadata.Key<String> key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
                        metadata.put(key, token);
                    }
                };
            }
        };

        SSLContext sslContext=null ;
        try {
            sslContext  = SSLContext.getInstance("TLS");
            sslContext .init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
            SSLContext.setDefault(sslContext );
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.setSslSocketFactory(sslSocketFactory);
        okHttpClient.setHostnameVerifier(new HostnameVerifier() {
            @Override public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        Channel channel=null;
        try {
            //ManagedChannel channel = OkHttpChannelBuilder.forAddress(ipaddr, Integer.valueOf(port))
                    channel = OkHttpChannelBuilder.forAddress(ipaddr, Integer.valueOf(port))
                    //.overrideAuthority("Vector")
                    .sslSocketFactory(sslSocketFactory)
                    .intercept(clientInterceptor)
                    .build();

            //ExternalInterfaceGrpc.ExternalInterfaceStub externalInterfaceStub = ExternalInterfaceGrpc.newStub(channel);
            ExternalInterfaceGrpc.ExternalInterfaceBlockingStub externalInterfaceBlockingStub = ExternalInterfaceGrpc.newBlockingStub(channel);

            Messages.SayTextRequest sayTextRequest = Messages.SayTextRequest
                    .newBuilder()
                    .setText("Yolo")
                    .build();

            Messages.SayTextResponse res = externalInterfaceBlockingStub.sayText(sayTextRequest);
            Log.d(TAG, res.getStatus().toString());
} catch (Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            pw.flush();
            Log.d(TAG,String.format("Failed... : %n%s", sw));
        } finally {
            Log.d(TAG,"finally");
            /*
            try {
                 if(channel!=null) {((ManagedChannel) channel).shutdown().awaitTermination(1, TimeUnit.SECONDS);}
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            */
        }

1 Ответ

0 голосов
/ 11 февраля 2019

Для ClientCall должен быть вызван start().start() не нужно вызывать при использовании заглушек, так как сами заглушки будут вызывать start().Но перехватчики подвергаются воздействию start().

Проблема в том, что ваша clientInterceptor:

protected void checkedStart(Listener listener, Metadata metadata) throws Exception {
    Metadata.Key<String> key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
    metadata.put(key, token);
    // FIXME: Missing call to delegate().start(listener, metadata);
}

заглушка называется start(), которая в итоге называется checkedStart() вашего перехватчика, но затемперехватчик не вызвал start на реальном ClientCall.

Обратите внимание, что вам не нужно использовать CheckedForwardingClientCall, поскольку ваш checkedStart() не вызывает никаких исключений.ForwardingClientCall - наиболее распространенный класс для использования.(Переопределить start() вместо checkedStart()).

...