且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用Firebase制作用户在线状态机制?

更新时间:2023-12-02 14:04:28

用户可以通过两种方式与Firebase数据库断开连接.

There are two ways the user can get disconnected from the Firebase Database.

  1. 干净的断开连接,客户端在断开连接之前向服务器发送信号.
  2. 肮脏的(由于缺乏更好的称呼)断开连接,在客户端可以发送信号之前,连接已关闭.

在完全断开连接的情况下,您的onDisconnect处理程序将立即触发,因此您的数据库将立即更新.

In the case of a clean disconnect, your onDisconnect handlers will immediately fire and thus your database will immediately be updated.

在断开连接很脏的情况下,Firebase依赖套接字层在远程客户端消失时发出信号.这可能需要花费几分钟的时间.但是最终,服务器将检测/确定客户端已消失,并且您的onDisconnect处理程序将会触发.

In the case of a dirty disconnect, Firebase depends on the socket layer to signal when the remote client is gone. This may take anywhere up to a few minutes. But eventually the server will detect/decide that the client is gone, and your onDisconnect handlers will fire.

数据结构中的一个小注释:您与用户之间的连接关系为1:1.不幸的是,事实并非如此.

A small note in your data structure: you that there is a 1:1 relation between a user and a connection. That is unfortunately not the case.

  • 用户可以从多个设备连接.如果它们现在与这些设备之一断开连接,则从该设备上的onDisconnect会将online设置为false,而它们仍可能连接在另一台设备上.
  • 移动设备/网络习惯于经历偶尔的断开/重新连接周期.这意味着即使在单个设备上,您也可能具有多个连接.如果断开连接很脏,当您已经为新的连接设置了onlinetrue时,onDisconnect处理程序可能会在以后触发.在这种情况下,挥之不去的onDisconnect处理程序会将online设置为false,而用户可能已经重新连接.
  • A user may be connected from multiple devices. If they now disconnect from one of those devices, the onDisconnect from that device will set online to false while they may still be connected on another device.
  • Mobile devices/networks have a habit of going through occasional disconnect/reconnect cycles. This means that you may have multiple connections, even on a single device. In case of a dirty disconnect, the onDisconnect handler may be fired much later, when you've already set online to true for the new connection. In such a case, your lingering onDisconnect handler will set online to false while the user may already be reconnected.

这就是说,您不应该依赖于用户与其连接之间的1:1关系. Firebase文档中的示例将连接视为集合并假定该用户已连接,只要该用户还有任何连接ID"(由push()生成)即可.我建议您这样做,以防止难以调试竞争条件和连接问题.

All this is to say that you should not rely on having a 1:1 relation between a user and their connection(s). The samples in the Firebase documentation treat connections as a collection and assume that the user is connected as long as there is any "connect ID" (generated by push()) left for that user. I recommend you do the same to prevent hard to debug race conditions and connection problems.