【问题标题】:Firebase persistance - onDisconnect with multiple browser windowsFirebase 持久性 - onDisconnect 与多个浏览器窗口
【发布时间】:2013-05-03 08:33:05
【问题描述】:

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

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

【问题讨论】:

    标签: javascript firebase


    【解决方案1】:

    .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 事件。这就是我提出多路径存在值的方法。

    【讨论】:

    • 谢谢@Kato!我选择了解决方案#1:如果变量脱机,请重置它。奇迹般有效。用户关闭辅助浏览器时的轻微闪烁对我们来说没什么大不了的。
    • 有一个边缘情况。当您在仍然登录的情况下注册新用户时,身份验证状态会更改 -> 以前的用户应该处于脱机状态,但 onDisconnect() 不会触发,因此存在幽灵用户。
    • 为避免这种情况,您必须确保在登录/注册之前注销并断开与 Firebase 的连接(检查 goOfflinesignOut 方法)。
    • 对不起,伙计们,错误的建议。只需确保在登录之前删除存在 ref(不是单个数组元素,而是整个数组)
    • 是否可以获得此处介绍的解决方案的完整示例?还是现在有更好的解决方案?
    【解决方案2】:

    另一个简单的解决方案(使用angularfire2,但使用纯firebase类似):

    const objRef = this.af.database.list('/users/' + user_id);
    const elRef = objRef.push(1);
    elRef.onDisconnect().remove();
    

    每次打开新选项卡时,都会向数组中添加一个新元素。 “onDisconnect”的引用与新元素有关,并且仅将其排除在外。

    当此数组为空时,用户将离线。

    【讨论】:

    • 这真是天才!
    猜你喜欢
    • 2017-08-18
    • 1970-01-01
    • 2023-03-15
    • 2010-11-02
    • 2016-07-14
    • 2012-03-14
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    相关资源
    最近更新 更多