我相信我可能不了解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()时都应该创建一个新的阻塞存根?我们将不胜感激在理解这一点上的任何帮助。
答案 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)
}