gRPC Android DEADLINE_EXCEEDED, но запрос к серверу не выполнен - PullRequest
0 голосов
/ 17 января 2019

Полагаю, я не понимаю, как работают каналы, заглушки и транспорты gRPC.У меня есть приложение для Android, которое создает канал и одну блокирующую заглушку и вставляет ее кинжалом при инициализации приложения.Когда мне нужно сделать вызов grpc, у меня в клиенте есть метод, который вызывает метод с этой заглушкой.После простоя приложения все мои вызовы возвращают ошибки DEADLINE_EXCEEDED, хотя в журналах сервера не отображаются вызовы.

@Singleton
@Provides
fun providesMyClient(app: Application): MyClient {
    val channel = AndroidChannelBuilder
            .forAddress("example.com", 443)
            .overrideAuthority("example.com")
            .context(app.applicationContext)
            .build()
    return MyClient(channel)
}

Где мой клиентский класс имеет функцию для возврата запроса сдедлайн:

class MyClient(channel: ManagedChannel) {
private val blockingStub: MyServiceGrpc.MyServiceBlockingStub = MyServiceGrpc.newBlockingStub(channel)

fun getStuff(): StuffResponse =
        blockingStub
                .withDeadlineAfter(7, TimeUnit.SECONDS)
                .getStuff(stuffRequest())
}
fun getOtherStuff(): StuffResponse =
        blockingStub
                .withDeadlineAfter(7, TimeUnit.SECONDS)
                .getOtherStuff(stuffRequest())
}

Я делаю вызовы на сервер внутри класса LiveData в Моем репозитории, где вызов выглядит так: myClient.getStuff ()

Я предполагаю, что каналв какой-то момент он теряет соединение, и тогда все последующие заглушки просто не могут соединиться, но я не вижу нигде в документации AndroidChannelBuilder, где говорится о том, как с этим справиться (я полагал, что он автоматически переподключается).Возможно ли, что канал, который я использую для создания моей заглушки блокировки, устарел, и мне следует создавать новую заглушку блокировки каждый раз, когда я вызываю getStuff ()?Любая помощь в понимании этого будет принята с благодарностью.

1 Ответ

0 голосов
/ 17 января 2019

После небольшого исследования я считаю, что проблема заключалась в том, что прокси на сервере закрывал соединение после нескольких минут простоя, и клиент ManagedChannel не обнаружил это автоматически и снова подключился, когда это произошло. При создании ManagedChannel я добавил к нему idleTimeout, который будет предварительно уничтожать соединение, когда оно бездействует, и восстанавливать его, когда оно понадобится снова, и это, похоже, решает проблему. Итак, новая конструкция канала выглядит так:

@Singleton
@Provides
fun providesMyClient(app: Application): MyClient {
    val channel = AndroidChannelBuilder
            .forAddress("example.com", 443)
            .overrideAuthority("example.com")
            .context(app.applicationContext)
            .idleTimeout(60, TimeUnit.SECONDS)
            .build()
    return MyClient(channel)
}
...