gRPC Android DEADLINE_EXCEEDED,但未向服务器发出请求

时间:2019-01-16 23:24:33

标签: android grpc grpc-java

我相信我可能不了解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 :(得分:0)

经过一些研究,我认为问题在于服务器的代理在闲置了几分钟后关闭了连接,并且客户端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)
}