Firebase onDisconnect()多次触发

时间:2016-07-01 17:47:14

标签: node.js firebase firebase-realtime-database

在firebase文档之后构建一个具有状态的应用程序,是否存在应用程序仍然连接时断开连接的情况?我们看到存在节点将应用程序显示为脱机,然后在我们没有丢失网络连接的几秒钟内重新联机的情况。

我们看到现场安装了多个嵌入式设备,其中存在设置为false,然后几乎立即恢复为真,并且它们在几秒钟内在所有设备上发生。从我们已经完成的测试和在线文档中我们知道,如果我们在设备上丢失了互联网连接,那么在服务器超时之前大约需要60秒才会触发onDisconnect()方法。

我们已经在presence方法中添加了代码,该方法允许设备在应用程序实际运行时看到presence节点设置为false,它会将状态重置为true。在发生这种情况时,我们会将单个写回写为true,这是它的结束,有时它就像服务器和客户端相互争斗,并且节点在50-200的过程中多次重置为true毫秒。每当我们强制存在恢复为真时,我们通过推送到设备GUID中的另一个节点来监视这一点。这仅在模块运行时以及最初建立存在之后发生。

以下是我们从设备上运行的各种模块调用的方法,以便我们可以在任何给定时间监视每个模块的状态。

exports.online = function (program, currentProgram) {
 var programPath = process.env.FIREBASE_DEVICES + process.env.GUID + '/status/' + program
  var onlinePath = process.env.FIREBASE_DEVICES + process.env.GUID + '/statusOnlineTimes/' + program
  var programRef = new firebase(programPath);
  var statusRef = new firebase(process.env.FIREBASE_DEVICES + process.env.GUID + '/status/bootup');
  var onlineRef = new firebase(onlinePath)
  amOnline.on('value', function(snapshot) {
    if (snapshot.val()) {
      programRef.onDisconnect().set(false);
      programRef.set(true);
      programRef.on('value', function(snapshot){
        if (snapshot.val() == false){
          programRef.set(true);
          console.log('[NOTICE] Resetting', program, 'module status back to True after Fireabase set to False')
          var objectToPush = {
            program: program,
            time: new Date().toJSON()
          }
          onlineRef.push(objectToPush)
        }
      })
      if (currentProgram != undefined) {
        statusRef.onDisconnect().set('Offline')
        statusRef.set(currentProgram)
      }
    }
  }); 

我们遇到的问题是Firebase是否曾调用onDisconnect()方法,即使它确实没有失去其状态?我们有一些实例,我们会看到设备脱机,然后在我们添加重置代码之前的60秒内重新联机。重置代码是为了解决我们在现场遇到的另一个问题,如果电源被设备中断并且它没有完全退出,设备可能会重新启动,并在之前的超时之前使用新的UID重置状态实例已被解雇。然后,一旦超时触发,即使设备实际上在线,设备也会显示为脱机。

1 个答案:

答案 0 :(得分:0)

因此,我们能够通过在programRef.on(...)调用之前直接添加programRef.off()调用来停止设备重新连接时发生的多次推送。我们决定要发生的事情是,只要设备从脱机状态上线并且amOnline.on(...)回调被触发,它就会创建一个新的监听器。

现在我们能够处理onDisconnect()从早期程序PID触发并覆盖状态为offline的当前活动程序的情况。这似乎解决了我们遇到的问题,即现场设备的竞争条件能够重新启动并在onDisconnect()触发之前重新获得连接,而该实例并未完全退出。

我们仍然遇到一个问题,即所有设备都会关闭,然后几乎同时重新上线(彼此间隔1-3秒)。是否有任何时候Firebase重置./info/connected节点?因为我们正在监控存在并实际登录和关闭事件,所以我们只是抓住了大多数人都看不到的事件?或者我们做错了什么?