Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

处理同步错误 — C++ SDK

在此页面上

  • 处理同步错误
  • 客户端重置
  • 自动与手动客户端重置
  • 指定客户端重置模式
  • 处理模式更改
  • 恢复未同步的更改
  • 丢弃未同步的更改
  • 手动客户端重置模式
  • 测试客户端重置处理

在开发使用 Device Sync 的应用程序时,应设置错误处理程序。 此错误处理程序可检测并响应任何失败的同步相关 API 调用。

sync_config上设置错误处理程序。 发生错误时, C++ SDK会使用sync_error对象和发生错误的sync_session来调用错误处理程序。

auto appConfig = realm::App::configuration();
appConfig.app_id = APP_ID;
auto app = realm::App(appConfig);
auto user = app.login(realm::App::credentials::anonymous()).get();
auto dbConfig = user.flexible_sync_configuration();
// Setting an error handler on the sync_config gives you access to
// sync_session and sync_error
dbConfig.sync_config().set_error_handler(
[](const realm::sync_session &session,
const realm::internal::bridge::sync_error &error) {
std::cerr << "A sync error occurred. Message: " << error.message()
<< std::endl;
});
auto syncRealm = realm::db(dbConfig);

提示

有关常见 错误的列表以及如何处理这些错误,请参阅Device Sync Atlas App ServicesDevice Sync文档中的 同步错误 。

使用Device Sync时,客户端重置是一项错误恢复任务,当服务器无法再与设备数据库同步时,客户端应用必须执行该任务。 在这种情况下,设备必须将其数据库重置为与服务器匹配的状态,才能恢复同步的能力。

发生这种情况时,设备上未同步的数据库可能包含尚未同步到服务器的数据。 SDK 可以尝试在客户端重置过程中恢复或丢弃该数据。

有关可能导致客户端重置的原因的更多信息,请Go Atlas App Services文档中的客户端重置。

SDK 提供了客户端重置模式,可自动处理大多数客户端重置错误。 客户端重置模式可将设备的数据库文件恢复到可同步状态,而无需关闭数据库或丢失通知。

manual()之外的所有客户端重置模式均会执行自动客户端重置。 模式之间的差异取决于它们如何处理设备上尚未同步到后端的更改。

选择recover_unsynced_changes()可自动处理大多数客户端重置情况。 这会尝试在客户端重置时恢复未同步的更改。

在某些情况下,您可能希望或需要设置手动客户端重置处理程序。 如果您的应用需要无法自动处理的特定客户端重置逻辑,您可能需要执行此操作。

C++ SDK 提供了在数据库配置中指定客户端重置处理程序的选项。 此客户端重置处理程序可以采用client_reset_mode_base 。 该结构体允许您指定:

  • 在客户端重置之前执行的区块

  • 客户端重置后要执行的区块

  • 处理客户端重置时使用的模式

auto user = app.login(realm::App::credentials::anonymous()).get();
auto syncConfig = user.flexible_sync_configuration();
// Set the client reset handler with your preferred client reset mode.
syncConfig.set_client_reset_handler(
realm::client_reset::recover_unsynced_changes(beforeReset, afterReset));
auto syncedRealm = realm::db(syncConfig);

您可以使用一种可用的客户端重置模式来指定 SDK 在客户端重置期间应如何尝试解析设备上的任何未同步数据:

  • recover_unsynced_changes()

  • recover_or_discard_unsynced_changes()

  • discard_unsynced_changes()

  • manual()

您可以指定在客户端重置过程中执行的前后区块。您可以使用它来执行对应用程序很重要的恢复逻辑。

/* You can define blocks to call before and after the client reset occur
if you need to execute specific logic, such as reporting or debugging. */
auto beforeReset = [&](realm::db before) {
/* A block called after a client reset error is detected, but before the
client recovery process is executed. You could use this block for any
custom logic, reporting, debugging etc. You have access to the database
before the client reset occurs in this block. */
};
auto afterReset = [&](realm::db device, realm::db server) {
/* A block called after the client recovery process has executed.
This block could be used for custom recovery, reporting, debugging etc.
You have access to the database that is currently on the device - the
one that can no longer sync - and the new database that has been
restored from the server. */
};

如果您的应用有特定的客户端恢复需求,则可以指定manual()客户端重置模式并设置手动客户端重置处理程序。 如果您的应用程序必须在客户端重置期间执行特定的自定义逻辑,或者客户端恢复规则不适用于您的应用程序,则可以执行此操作。

客户端恢复配置 Device Sync时默认启用的功能。 启用客户端恢复后,大多数情况下 SDK 可以自动管理客户端重置过程。 当您进行模式更改时:

  • 当没有模式更改或非中断性模式更改时,客户端可以恢复未同步的更改。

  • 当您进行中断性模式更改时,客户端自动重置模式会转而使用手动错误处理程序。 您可以针对这种情况设置手动客户端重置错误处理程序。 当您的应用程序进行中断性模式更改时,无法进行客户端自动恢复。

有关中断性与非中断性模式更改的信息,请参阅中断性与非中断性更改快速参考。

在客户端重置期间,客户端应用程序可以尝试在尚未同步到后端的设备上恢复已同步数据库中的数据。 要恢复未同步的更改,必须 在 App Services App 中启用 客户端恢复 (默认启用)。

如果希望应用恢复尚未同步的更改,请使用以下客户端恢复模式之一:

  • recover_unsynced_changes():客户端尝试恢复未同步的更改。 如果您不想丢弃未同步的更改,请选择此模式。

  • recover_or_discard_unsynced_changes():客户端首先尝试恢复尚未同步的更改。 如果客户端无法恢复未同步的数据,则会放弃未同步的更改,但会继续自动执行客户端重置。 当您想要启用客户端自动恢复以丢弃未同步的更改时,请选择此模式。

auto user = app.login(realm::App::credentials::anonymous()).get();
auto syncConfig = user.flexible_sync_configuration();
// Set the client reset handler with your preferred client reset mode.
syncConfig.set_client_reset_handler(
realm::client_reset::recover_unsynced_changes(beforeReset, afterReset));
auto syncedRealm = realm::db(syncConfig);

有时,客户端重置操作可能无法在recover_unsynced_changes()模式完成,例如当存在中断性模式更改或在Device Sync配置中禁用客户端恢复时。 要处理这种情况,您的应用可以在同步错误处理程序中处理客户端重置错误。 有关更多信息,请参阅本页上的手动客户端重置模式部分。

启用客户端恢复后,这些规则将决定如何集成对象,包括当后端和客户端都对同一对象进行更改时如何解决冲突:

  • 同步在客户端重置之前未同步的本地创建的对象。

  • 如果一个对象在服务器上被删除,但在恢复的客户端上被修改,则删除优先,客户端丢弃更新。

  • 如果在正在恢复的客户端上删除了对象,而不是在服务器上删除了对象,则客户端将应用服务器的删除指令。

  • 如果对同一字段的更新发生冲突,则应用客户端更新。

discard_unsynced_changes()客户端重置模式会永久删除设备上自上次成功同步以来所有未同步的更改。 当您的应用需要与 Device Sync客户端恢复规则不一致的客户端恢复逻辑,或者您不想恢复未同步的数据时,可以使用此模式。

如果您的应用程序不能丢失尚未同步到后端的设备数据,请勿使用丢弃未同步的更改模式。

要执行自动客户端重置以丢弃未同步的更改,请使用discard_unsynced_changes()客户端重置模式。

auto user = app.login(realm::App::credentials::anonymous()).get();
auto syncConfig = user.flexible_sync_configuration();
// Set the client reset handler with your preferred client reset mode.
syncConfig.set_client_reset_handler(
realm::client_reset::discard_unsynced_changes(beforeReset, afterReset));
auto syncedRealm = realm::db(syncConfig);

注意

丢弃并恢复

如果您想尝试恢复未同步的更改,但放弃任何无法恢复的更改,请参阅本页恢复未同步的更改部分中的recover_or_discard_unsynced_changes()文档。

有时,客户端重置操作可能无法在discard_unsynced_changes()模式下完成,例如发生中断性模式更改时。 要处理这种情况,您的应用可以在同步错误处理程序中处理客户端重置错误。 有关更多信息,请参阅本页上的“手动客户端重置模式”部分。

使用manual()客户端重置模式时,必须在同步错误处理程序中实现自定义客户端重置处理程序。 我们建议尽可能使用客户端自动恢复模式,并且仅当自动恢复逻辑不适合您的应用时才选择manual()模式。

auto user = app.login(realm::App::credentials::anonymous()).get();
auto syncConfig = user.flexible_sync_configuration();
// Set the client reset handler to manual client reset mode.
syncConfig.set_client_reset_handler(realm::client_reset::manual());
// Define a Sync error handler for handling the client reset.
syncConfig.sync_config().set_error_handler(
[&](realm::sync_session session, realm::sync_error error) {
if (error.is_client_reset_requested()) {
/* You might use this for reporting or to instruct the user to delete
and re-install the app. */
};
});
auto syncedRealm = realm::db(syncConfig);

如果客户端重置操作无法自动完成(例如发生中断性模式更改时),则客户端重置过程将由手动错误处理程序完成。 在以下任何一种客户端重置模式下都可能会出现这种情况:

  • recover_unsynced_changes()

  • recover_or_discard_unsynced_changes()

  • discard_unsynced_changes()

我们建议将手动处理程序视为致命错误恢复情况的工具,在这种情况下,您建议用户更新应用或执行某些其他操作。

您可以通过终止并重新启用 Device Sync 来手动测试应用程序的客户端重置处理。

当您终止并重新启用 Sync 时,之前使用 Sync 连接的客户端在执行客户端重置之前无法进行连接。 终止同步会从服务器中删除允许客户端同步的元数据。 客户端必须从服务器下载 Realm 的新副本。 服务器向这些客户端发送客户端重置错误。 因此,当您终止同步时,就会trigger客户端重置条件。

要测试客户端重置处理,请执行以下操作:

  1. 从客户端应用程序写入数据并等待其同步。

  2. 终止并重新启用 Device Sync。

  3. 再次运行客户端应用程序。 当应用尝试连接到服务器时,应该会出现客户端重置错误。

警告

当您在客户端应用程序中迭代进行客户端重置处理时,您可能需要反复终止并重新启用 Sync。 终止并重新启用同步会导致所有现有客户端在完成客户端重置之前无法进行同步。 为了避免在生产中出现这种情况,请在开发环境中测试客户端重置处理。

后退

管理同步会话