java - 在 Firestore Java admin SDK 中网络断开和重新连接时未收到文档更新
问题描述
我正在使用 Java 管理 SDK 在本地 PC 的 Firestore 中设置一个查询手表。如果网络断开并重新连接,则我的本地计算机不再接收更新。我观察到,如果网络重新连接发生在很短的时间间隔内(< 2 - 3 分钟),那就没问题了。但是,如果它更长,则会发生此问题。此外,侦听器回调中不会通知错误/异常,因此我可以再次设置监视以进行更新。我的电脑不在代理后面,所以它不可能是代理问题。
请帮助我调试此问题。
编辑:
看起来这是 SDK 中的错误。我启用了 SDK 日志并尝试了以下实验:
场景一:
- 关注查询更新
- 客户端与服务器建立 GRPC 连接。
- 看起来服务器每分钟向客户端发送一个保持活动状态(?),但从客户端到服务器没有保持活动状态
- 断开网络
- 一分钟内重新连接,查询连接仍处于活动状态,文档更新按预期到达
- 断开网络
- 5分钟后重新连接
- 这里我的猜测是服务器会从它的一端重置 GRPC 连接,因为它无法到达客户端,但 SDK 不知道这一点。它仍然期待服务器发送保持活动状态。
- 客户端没有收到文档更新(如预期的那样)
- 发出新查询并注意其更新。
- SDK 尝试通过它之前建立的同一 GRPC 连接发送查询,意识到连接已关闭,打开一个新的 GRPC 连接。现在,两个查询的文档更新都开始了。
场景二:
- 关注查询更新
- 断开网络约 5 分钟
- 在重新连接网络之前发出新的查询。
- SDK 尝试通过它之前建立的同一 GRPC 连接发送查询,意识到连接已关闭,打开一个新的 GRPC 连接。即使这失败了,但连接尝试每分钟重试一次。
- 重新连接网络。
- SDK 的连接尝试成功,并且两个查询的更新都开始出现。
解决方案
必须启用 GRPC keepalive,客户端才能将 keepalive 发送到服务器并检测任何从服务器端关闭的连接。这可以通过TransportChannelProvider
在FirestoreOptions
初始化时提供FirebaseApp
。代码片段如下:
InstantiatingGrpcChannelProvider channelProvider =
InstantiatingGrpcChannelProvider.newBuilder()
.setKeepAliveTime(Duration.ofSeconds(60L))
.setKeepAliveTimeout(Duration.ofMinutes(5L))
.build();
FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
.setChannelProvider(channelProvider).build();
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(credentials).setFirestoreOptions(firestoreOptions)
.setConnectTimeout(5000).setReadTimeout(5000).build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(options);
Firestore firestore = FirestoreClient.getFirestore(firebaseApp);
推荐阅读
- python - 绘制 y 轴为百分比的直方图(使用 FuncFormatter?)
- c# - 获取合作伙伴中心 SDK 对账数据
- python-2.7 - 您如何在具有不同 x 轴分辨率的两条线之间进行填充?
- c# - 实体框架写入上下文而不是数据库
- javascript - 解决 JavaScript 中的代码注入
- android - 设备进入深度睡眠时的 Android 作业调度程序行为
- c# - 在 asp.net mvc 中设置用户对每个应用程序的访问权限
- python - 方法不允许 Flask
- bootstrap-4 - bootstrap 4.1 删除了 pull-md-16(列拉/推)
- python - Keras LSTM 神经网络:TypeError:LSTM() 缺少 1 个必需的位置参数:'Y'