.info/connected 存在数据仅告诉给定客户端是否已链接到 Firebase 服务器,因此在这种情况下它对您没有帮助。您可以尝试以下方法之一:
如果变量离线则重置它
如果您有多个客户端监视同一个变量(多个窗口属于此类别),那么很自然地期望它们在存在值上发生冲突。让每个人监控变量的变化并根据需要进行更正。
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');
}
});
这实现起来既快速又容易,但可能会很烦人,因为我的状态可能会闪烁到离线,然后为其他客户重新在线。当然,这可以通过在任何更改事件触发 UI 更新之前对其进行短暂延迟来解决。
为每个连接提供自己的路径
既然onDisconnect的目的是告诉你某个特定的客户端是否下线,那么我们自然应该给每个客户端自己的连接:
var ref = firebaseRef.child(MY_ID).child('status').push(1);
ref.onDisconnect().remove();
在此用例中,每个连接的客户端都会在status 下添加一个新子级。如果路径不为空,则至少连接了一个客户端。
通过在status 寻找一个真实值来检查在线状态实际上相当简单:
firebaseRef.child(USER_ID).child('status').on('value', function(ss) {
var isOnline = ss.val() !== null;
});
这样做的一个缺点是您实际上只有 status 的 thruthy 值(您不能将其设置为“空闲”与“在线”之类的值),尽管这也可以通过一点点来解决独创性。
在这种情况下交易不起作用
我的第一个想法是尝试事务,因此您可以在每个窗口打开/关闭时增加/减少计数器,但似乎没有 transaction 方法关闭 onDisconnect 事件。这就是我提出多路径存在值的方法。