【发布时间】:2015-01-09 15:04:02
【问题描述】:
我有一个使用 PouchDB 的移动应用程序,它监听来自远程 CouchDB 服务器的更改。有时,应用程序会推动它自己的更改。有没有办法检查我是否仍有与远程 CouchDB 实例的活动“连接”?
到目前为止,我能想到的最佳解决方案是定期调用 db.info 并查看我是否收到错误消息,但这似乎有点冒险。
【问题讨论】:
我有一个使用 PouchDB 的移动应用程序,它监听来自远程 CouchDB 服务器的更改。有时,应用程序会推动它自己的更改。有没有办法检查我是否仍有与远程 CouchDB 实例的活动“连接”?
到目前为止,我能想到的最佳解决方案是定期调用 db.info 并查看我是否收到错误消息,但这似乎有点冒险。
【问题讨论】:
我假设您包含了pouchdb 标签,因为您在本地使用 PouchDB 并在本地 PouchDB 和远程 CouchDB 之间进行复制。假设如此,PouchDB 中的复制是一个事件发射器,因此您可以在 sync 或 replicate 调用中定义许多不同的事件,see the docs 包括 error 事件。
【讨论】:
您是否尝试在连接丢失时发出的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)
});
如果您使用实时复制,则在复制等待更改且err 为undefined 时会发出paused 事件。如果出现连接中断之类的问题,还会发出 paused 事件,但带有 err 参数。
注意:我确信有更安全的方法来检查 err 是否已定义。
paused (err) - 当复制暂停时触发此事件,或者 因为实时复制正在等待更改,或者复制已 暂时失败,出现错误,正在尝试恢复。
【讨论】:
err 是 undefined
您需要将“重试”设置为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}`);
});
【讨论】:
据我所知,PouchDB 没有任何事件通知我们同步因互联网连接中断而停止。我做了一个小技巧来解决这个问题。
当同步正常发生并且您对本地 PouchDB 进行更改时,触发事件的顺序是:
但是,当网络中断时,顺序是:
没有发生与远程数据库同步时不会触发更改事件。
所以,我所做的是为活动和更改事件分别设置了两个标志pouchDbSyncActiveEvent 和pouchDbSyncChangeEvent,并将两者都初始化为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 事件侦听器方法,但最好按照它们的执行顺序编写它们:)
【讨论】: