onDisconnect 在客户端重新连接时触发

Posted

技术标签:

【中文标题】onDisconnect 在客户端重新连接时触发【英文标题】:onDisconnect fires when client reconnects 【发布时间】:2022-01-22 00:20:55 【问题描述】:

我正在收听.info/connected 以确定我的设备是否在线。如果它在线,它会将具有设备 ID 的孩子添加到数据库中。

_firebaseDatabase.reference().child('.info/connected').onValue.listen((event) 
  if (event.snapshot.value == true) 
    setDeviceOnline(userUid: uid, deviceUid: deviceUid)
  
);

我正在使用 Firebase 实时数据库上的 onDisconnect 回调在相应客户端断开连接时删除此设备 ID。

Future<void> setDeviceOnline(String userUid, String deviceUid) async 
  DatabaseReference currentDeviceConnection = _firebaseDatabase.reference().child('users/$userUid/connections').push();

  // Add this device to my connections list
  await currentDeviceConnection.set(deviceUid);

  // When I disconnect, remove this device
  currentDeviceConnection.onDisconnect().remove();

现在:

    当客户端明确断开连接时,onDisconnect 会触发并从数据库中删除设备 ID。 当我打开 airplane mode 时,onDisconnect 在短暂超时后触发并从数据库中删除设备 ID。 当我打开airplane mode 并在此超时发生之前将其关闭时,onDisconnect 在客户端重新连接时立即触发。就像它告诉数据库“我离线了”

第 3 点的问题是当客户端重新连接时,onDisconnect 触发并从数据库中删除当前 ID,并且由于 .info/connected 侦听器再次显示 event.snapshot.value == true,它立即使用设备添加一个新子代id 到数据库。

我认为这按预期工作。所以我不认为这是一个错误。但是如果数据库中仍然存在相应的孩子,有没有办法防止删除孩子并添加新的孩子?

【问题讨论】:

【参考方案1】:

一旦服务器检测到原始连接已消失(无论是它自己,还是因为客户端告诉它),它就会执行您为该连接设置的 onDisconnect 处理程序。

没有办法阻止删除之前的连接节点。

但是由于建立了新的连接,您的setDeviceOnline 应该再次生成一个新的currentDeviceConnection 连接ID。事实上,这正是 Firebase 文档中的在线状态系统每次重新连接时都会生成一个新 ID 的原因。这不是发生在你身上吗?

【讨论】:

嗨弗兰克。感谢您的回复。是的,它正在发生在我身上。因此,即使数据库本身还没有注意到客户端的缺席,客户端告诉数据库短时间离线然后数据库触发onDisconnect 是正常的吗?我的意思是onDisconnect 的触发并不是真正必要的,因为客户端已经重新连接。我希望我解释得足够好。 有来自同一个客户端的新连接,但旧连接仍然消失。在您的代码中,我期望您为新连接获得一个新的推送 ID,然后旧的推送 ID 会立即消失,或者在服务器检测到它时消失(当套接字超时时会发生这种情况)。如果这不是您看到的情况,您能显示数据库的屏幕截图/gif 吗?

以上是关于onDisconnect 在客户端重新连接时触发的主要内容,如果未能解决你的问题,请参考以下文章

如何从SignalR客户端端确定服务器断开连接

Firebase:onDisconnect 事件何时触发?

如果应用程序进入后台模式,则会触发 Ondisconnect

IONIC 2 native Network.onDisconnect() 运行代码两次

rxjs websocket:心跳和重新连接

Firebase 连接检测在 60 秒后不起作用