我正在使用Java admin SDK在本地PC的Firestore中设置查询 . 如果网络断开连接并重新连接,则本地计算机将不再接收更新 . 我观察到,如果网络重新连接发生在一个短的间隔(<2-3个分钟),那么它是好的 . 但如果它更长,那么这个问题就会发生 . 此外,监听器回调中不会通知任何错误/异常,因此我可以再次为更新设置监视 . 我的PC不在代理之后,所以它不能成为代理问题 .
请帮我调试这个问题 .
编辑:
看起来这是SDK中的一个错误 . 我启用了SDK日志并尝试了以下实验:
-
场景1:
-
注意查询更新
-
客户端与服务器 Build GRPC连接 .
-
看起来服务器每分钟都向客户端发送一个keep alive(?),但是从客户端到服务器没有保持活动状态
-
断开网络连接
-
在一分钟内重新连接,查询连接仍处于活动状态,文档更新按预期到达
-
断开网络连接
-
5分钟后重新连接
-
在这里,我的猜测是服务器将从其末端重置GRPC连接,因为它无法到达客户端,但SDK不知道这一点 . 它仍然期望服务器发送保持活动 .
-
客户端未收到任何文件更新(如预期)
-
发出新查询并观察其更新 .
-
SDK尝试通过先前 Build 的相同GRPC连接发送查询,意识到连接已关闭,打开新的GRPC连接 . 现在,两个查询的文档更新都将开始 .
-
场景2:
-
注意查询更新
-
断开网络连接约5分钟
-
在重新连接网络之前发出新查询 .
-
SDK尝试通过先前 Build 的相同GRPC连接发送查询,意识到连接已关闭,打开新的GRPC连接 . 即使这样也会失败,但每分钟都会重试连接尝试 .
-
重新连接网络 .
-
SDK的连接尝试成功,两个查询的更新开始 .
2 回答
必须启用GRPC keepalive,以便客户端向服务器发送keepalive并检测从服务器端关闭的任何连接 . 这可以通过在初始化
FirebaseApp
时在FirestoreOptions
中提供TransportChannelProvider
来完成 . 代码段如下:当您正在侦听Cloud Firestore数据库中的更改并且您有一些网络断开连接时,遗憾的是您无能为力 . 您无法控制Firebase Firestore SDK如何管理其连接 .
重试没有像你期望的那么快发生的原因是因为执行重试的代码没有使用所谓的exponential backoff算法 . 这意味着此代码可以快速阻止用户设备上发生的所有重试,从而有利于提高性能 . 太多的重试也可能通过消耗他的数据计划的过多带宽而影响用户 .
作为结论,这意味着重新获得连接可能需要一些时间,您应该对此保持耐心 .