Firebase持久性 - onDisconnect与多个浏览器窗口

Mic*_*ham 7 javascript firebase

我们正在编写一个监控在线状态的应用程序.在多种情况下,我们需要用户打开多个浏览器窗口.我们遇到的问题是,在辅助浏览器窗口中打开并运行firebase js代码后,用户将关闭该辅助窗口.这会将它们的状态设置为在主窗口中脱机,因为onDisconnect事件在辅助窗口中触发.

这种情况有解决方法吗?这是否可以使用特殊的/.info/connected位置?

Kat*_*ato 8

.info/connected存在的数据只告诉一个给定的客户,如果他们被链接到火力地堡服务器,因此它不会帮助你在这种情况下.你可以试试其中一个:

如果变量脱机,请重置该变量

如果您有多个客户端监视同一个变量(多个窗口属于此类别),那么期望它们与存在值冲突是很自然的.让每个人监视变量以进行更改并根据需要进行更正.

var ref = firebaseRef.child(MY_ID).child('status');
ref.onDisconnect().remove();
ref.on('value', function(ss) {
   if( ss.val() !== 'online' ) {
      // another window went offline, so mark me still online
      ss.ref().set('online');
   }
});
Run Code Online (Sandbox Code Playgroud)

这很快且易于实现,但可能很烦人,因为我的状态可能会闪烁到脱机状态,然后再联机到其他客户端.当然,这可以通过在触发UI更新之前对任何更改事件进行短暂延迟来解决.

为每个连接提供自己的路径

由于目的onDisconnect是告诉您特定客户端是否脱机,因此我们应该自然地为每个客户端提供自己的连接:

var ref = firebaseRef.child(MY_ID).child('status').push(1);
ref.onDisconnect().remove();
Run Code Online (Sandbox Code Playgroud)

在这个用例中,每个连接的客户端都会添加一个新的子节点status.如果路径不为null,则至少连接一个客户端.

通过在以下位置查找真实值来检查在线状态实际上相当简单status:

firebaseRef.child(USER_ID).child('status').on('value', function(ss) {
    var isOnline = ss.val() !== null;
});
Run Code Online (Sandbox Code Playgroud)

这样做的一个缺点是你真的只有一个价值status(你不能把它设置为"空闲"和"在线"之类的东西),虽然这也可以通过一点点聪明才能解决.

在这种情况下,事务不起作用

我的第一个想法是尝试一个事务,所以你可以在每个窗口打开/关闭时增加/减少一个计数器,但似乎没有一个transaction方法离开onDisconnect事件.这就是我想出多路径存在价值的方式.