22

我正在尝试评估使用 IndexedDB 解决离线问题。它将填充当前存储在 MongoDB 数据库中的数据(按原样)。

一旦数据存储在 IndexedDB 中,它可能会在 MongoDB 服务器上发生更改,我需要传播这些更改。是否有任何现有的框架或库可以为 Mongo做这样的事情。我已经知道 CouchDB/PouchDB 并且没有探索这两个。

4

3 回答 3

3

[ 2021 年同步解决方案]

我知道所问的问题是专门针对 MongoDB 的,但由于这是一个旧线程,我认为读者可能正在为新应用程序或重建寻找其他解决方案。我真的可以推荐查看AceBase,因为它完全符合您当时的要求。

AceBase 是一个免费和开源的实时数据库,可以在浏览器和服务器数据库之间轻松存储和同步。它在浏览器中使用 IndexedDB,在服务器上使用自己的二进制 db / SQL Server / SQLite 存储。离线编辑在重新连接时同步,客户端通过 websocket(FAST!)实时通知远程数据库更改。

最重要的是,AceBase 有一个称为“实时数据代理”的独特功能,它允许您对内存中对象的所有更改进行持久化并同步到本地和服务器数据库,以及远程更改以自动更新您的内存中对象. 这意味着您可以完全忘记数据库编码,并像只使用本地对象一样进行编码。无论您是在线还是离线。

以下示例展示了如何在浏览器中创建本地 IndexedDB 数据库,如何连接到与本地数据库同步的远程数据库服务器,以及如何创建实时数据代理以消除进一步的数据库编码。AceBase 也支持身份验证和授权,但为了简单起见,我省略了它。

const { AceBaseClient } = require('acebase-client');
const { AceBase } = require('acebase');

// Create local database with IndexedDB storage:
const cacheDb = AceBase.WithIndexedDB('mydb-local');

// Connect to server database, use local db for offline storage:
const db = new AceBaseClient({ dbname: 'mydb', host: 'db.myproject.com', port: 443, https: true, cache: { db: cacheDb } });

// Wait for remote database to be connected, or ready to use when offline:
db.ready(async () => {

    // Create live data proxy for a chat:
    const emptyChat = { title: 'New chat', messages: {} };
    const proxy = await db.ref('chats/chatid1').proxy(emptyChat);  // Use emptyChat if chat node doesn't exist

    // Get object reference containing live data:
    const chat = proxy.value;

    // Update chat's properties to save to local database, 
    // sync to server AND all other clients monitoring this chat in realtime:
    chat.title = `Changing the title`;
    chat.messages.push({ 
        from: 'ewout', 
        sent: new Date(),
        text: `Sending a message that is stored in the database and synced automatically was never this easy!` +
              `This message might have been sent while we were offline. Who knows!`
    });

    // To monitor and handle realtime changes to the chat:
    chat.onChanged((val, prev, isRemoteChange, context) => {
        if (val.title !== prev.title) { 
            alert(`Chat title changed to ${val.title} by ${isRemoteChange ? 'us' : 'someone else'}`); 
        }
    });
});

有关更多示例和文档,请参阅npmjs.com上的 AceBase实时数据库引擎

于 2021-03-18T20:07:18.987 回答
1

Open up a changeStream with the resumeToken. There's no guarantee of causal consistency however since we're talking multiple disparate databases.

于 2020-12-16T23:38:20.677 回答
0

我没有使用过 IndexDB,但设计问题并不少见。我对您的应用程序的理解是,当客户端与 MongoDB 建立连接时,您将一组文档拉下来用于本地存储并断开连接。客户端然后可以在本地做事(不连接到数据服务器),然后推送更改。

在我看来,您必须处理两种一般情况:

  1. 当 MongoDB 服务器更新并中断与客户端的连续性时,客户端将不得不
    1. 轮询数据(计时器?)或
    2. 保持 websocket 打开,让通知在管道上自由流动
  2. 当用户需要将更改的数据推送回管道时
    1. 您可以异步重新连接,检查状态更改,(根据您的业务规则解决冲突)
    2. 有一个用于处理冲突的服务器端(轻量级)接口(取决于您的应用程序的复杂性,将 MongoDB 中状态更改的时间戳与 IndexedDB 更新进行比较就足够了)
于 2012-08-31T10:02:51.003 回答