【问题标题】:How to know when we've lost sync with a remote CouchDB如何知道我们何时失去与远程 CouchDB 的同步
【发布时间】:2015-01-09 15:04:02
【问题描述】:

我有一个使用 PouchDB 的移动应用程序,它监听来自远程 CouchDB 服务器的更改。有时,应用程序会推动它自己的更改。有没有办法检查我是否仍有与远程 CouchDB 实例的活动“连接”?

到目前为止,我能想到的最佳解决方案是定期调用 db.info 并查看我是否收到错误消息,但这似乎有点冒险。

【问题讨论】:

    标签: couchdb pouchdb


    【解决方案1】:

    我假设您包含了pouchdb 标签,因为您在本地使用 PouchDB 并在本地 PouchDB 和远程 CouchDB 之间进行复制。假设如此,PouchDB 中的复制是一个事件发射器,因此您可以在 syncreplicate 调用中定义许多不同的事件,see the docs 包括 error 事件。

    【讨论】:

    • 你是对的,我正在使用 pouchCB。我忘了提那个。当“连接”丢失时,复制和同步选项不会触发事件。如果您失去互联网连接会发生什么?在您尝试推动更改之前,您将不知道发生了任何事情..“倾听”似乎默默地失败了。
    • 哦,对了。我明白你现在想要什么了。我不确定是否有任何方法可以做到这一点。整个想法是您不关心连接是打开还是关闭,您只需使用本地 PouchDB 并且只要连接恢复,同步就会恢复。
    • 便便。我想我可以回去用 db.info 定期检查连接。
    • 让我问一下,为什么你关心连接何时上升/下降?
    • 当“连接”断开时,我需要提醒用户他们将不再接收更新。我还需要禁止用户发送更新(如果连接断开,更新将排队)。
    【解决方案2】:

    您是否尝试在连接丢失时发出的paused 事件中查找错误?

    localDB.replicate.to(remoteDB, {
      live: true,
      retry: true,
    }).on('paused', (err) =>{
      console.log('paused');
      if (err) {
        alert(`No connection! ${err}`);
      }
      // replication was paused, usually because of a lost connection
    }).on('change', (change)=>{
      // yo, something changed!
    }).on('active', (info)=>{
      // replication was resumed
    }).on('error', (err)=>{
      // totally unhandled error (shouldn't happen)
    });
    

    如果您使用实时复制,则在复制等待更改且errundefined 时会发出paused 事件。如果出现连接中断之类的问题,还会发出 paused 事件,但带有 err 参数。

    注意:我确信有更安全的方法来检查 err 是否已定义。

    来自PouchDB documentation

    paused (err) - 当复制暂停时触发此事件,或者 因为实时复制正在等待更改,或者复制已 暂时失败,出现错误,正在尝试恢复。

    【讨论】:

    • 试过 - 不起作用。开始同步,然后关闭远程数据库 - 暂停 errundefined
    • 同步完成后也暂停触发。 Pouchdb 7.0,0
    【解决方案3】:

    您需要将“重试”设置为false,否则错误事件不会被捕获。

    来自 API 参考:

    error (err) - 当复制由于不可恢复的故障而停止时触发此事件。如果 retry 为 false,这也会在用户离线或发生其他网络错误时触发(因此,如果需要,您可以自己处理重试)。

    试试这个代码:

        // Sync pouch - couch
    db.sync(couch, {
        live: true,
        retry: false
    }).on('error', (err) => {
        console.log(`A sync error occurred: ${err}`);
    });
    

    【讨论】:

      【解决方案4】:

      据我所知,PouchDB 没有任何事件通知我们同步因互联网连接中断而停止。我做了一个小技巧来解决这个问题。

      当同步正常发生并且您对本地 PouchDB 进行更改时,触发事件的顺序是:

      1. 活动
      2. 改变
      3. 暂停

      但是,当网络中断时,顺序是:

      1. 活动
      2. 暂停

      没有发生与远程数据库同步时不会触发更改事件。

      所以,我所做的是为活动和更改事件分别设置了两个标志pouchDbSyncActiveEventpouchDbSyncChangeEvent,并将两者都初始化为false。在'active' 事件的回调中将pouchDbSyncActiveEvent 转换为true。无论是否有互联网,它都会运行。在'change' 事件的回调中将pouchDbSyncChangeEvent 转换为true。如果没有互联网,这将不会运行,pouchDbSyncChangeEvent 仍将保持false,并且'paused' 事件将很快被触发。这会通知我们同步已停止。

      代码

      let pouchDbSyncActiveEvent = false
      let pouchDbSyncChangeEvent = false
      
      localPouchDb.sync(remoteCouchDb, {
        live: true,
        retry: true
      })
      .on('active', (change) => {
      
        pouchDbSyncActiveEvent = true
      
      })
      .on('change', (change) => {
      
        pouchDbSyncChangeEvent = true
      
      })
      .on('paused', (info) => {
      
        if(pouchDbSyncActiveEvent == true && pouchDbSyncChangeEvent == false){
      
          // Gotcha! Syncing with remote DB not happening!
      
        }
        else {
      
          // Everything's ok. Syncing with remote DB happening normally.
      
        }
      
        pouchDbSyncActiveEvent = false
        pouchDbSyncChangeEvent = false
      
      })
      

      注意: 您可以按照您希望的顺序编写.on 事件侦听器方法,但最好按照它们的执行顺序编写它们:)

      【讨论】:

      • 问题的最佳答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 2016-01-07
      • 1970-01-01
      相关资源
      最近更新 更多