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

配置并打开同步 Realm - .NET SDK

在此页面上

  • 同步 Realm
  • 已同步 Realms 与非同步 Realms
  • 在同步 Realm 和非同步 Realm 之间转换
  • 同步 Realm
  • 打开同步 Realm
  • 在线时打开同步 Realm
  • 离线时打开同步 Realm
  • 使用 AppConfiguration 配置超时
  • 确定 Realm 范围
  • 类子集

您可以配置 Realm,以在许多设备之间自动同步数据,并且每个设备都有自己的本地数据副本。同步 Realm 使用与纯本地 Realm 不同的配置,并且需要 Atlas App Services 后端处理同步过程。

应用程序始终可以在本地创建、修改和删除同步的 Realm 对象,即使在离线状态下也是如此。只要网络连接可用,Realm SDK 就会建立与应用程序服务器的连接,并与其他客户端进行双向更改同步。 Atlas Device Sync 协议和服务器端操作转换可确保 Realm 的所有完全同步实例看到完全相同的数据,即使某些更改发生在离线状态和/或接收时无序。

提示

了解如何配置和使用 Sync

有关 Device Sync 的详细信息,包括如何在 App Services App 中设置同步的说明,请参阅在设备之间同步数据 - .NET SDK。

已同步 Realm 与非同步本地 Realm 有几个不同之处:

  • 同步 Realm 尝试将更改与后端 App Services App 同步,而非同步 Realm 则不会。

  • 同步 Realm 可以由经过身份验证的用户访问,而非同步 Realm 没有用户或身份验证的概念。

您可以将数据从非同步 Realm 复制到同步 Realm,反之亦然,但无法同步非同步 Realm。

要将非同步 Realm 转换为同步 Realm,您可以按照将仅限本地的应用迁移到启用同步的应用中描述的过程进行操作。 .NET SDK 还提供WriteCopy()方法,使您能够将非同步 Realm 的数据复制到同步 Realm。有关更多信息,请参阅从非同步 Realm 迁移到同步 Realm。

注意

仅限基于分区的同步

此方法仅支持在非同步 Realm 和基于分区的同步之间进行转换。如果应用程序使用“灵活同步”,则必须手动遍历一个 Realm 中的对象,并将其复制到另一个 Realm。

要打开同步 Realm,您必须拥有经过身份验证的User对象。要获取初始 User实例,您需要对 Atlas App Services 后端进行身份验证,这要求设备在用户首次登录时处于在线状态。发生初始身份验证后,您可以检索现有用户离线时。

注意

用户首次登录您的应用时,您应异步打开域,以在背景线程中将数据从服务器同步到设备。初始同步后,您可以同步打开一个 域,以确保应用程序在离线状态下运行。

打开同步 Realm 的典型流程包括:

  1. 验证用户身份。

  2. 创建同步配置。

  3. 使用配置打开用户的已同步 Realm。

在身份验证时,我们将用户凭证缓存在设备上的 sync_metadata.realm 文件中。

当您在身份验证后打开同步 Realm 时,您可以跳过登录流程,并利用之前创建的相同同步配置直接打开同步 Realm。

使用缓存的凭证,可以:

  • 立即使用设备上的数据打开同步 Realm。您可以离线或在线使用此方法。

  • 从应用程序下载更改后,打开同步 Realm。这要求用户具备有效的互联网连接。

在线打开同步 Realm 的步骤如下:

  1. 您的应用代码将引导用户完成身份验证。

  2. 创建一个包含 User 对象的 FlexibleSyncConfiguration 对象。

  3. 通过调用GetInstanceAsync()方法打开同步 Realm。

  4. 如果您的FlexibleSyncConfiguration不包含初始订阅,请添加订阅。

以下代码演示了这些步骤:

var app = App.Create("myRealmAppId");
var user = await app.LogInAsync(Credentials.Anonymous());
Realm realm;
var config = new FlexibleSyncConfiguration(user)
{
PopulateInitialSubscriptions = (realm) =>
{
var allTasks = realm.All<MyTask>();
realm.Subscriptions.Add(allTasks, new SubscriptionOptions { Name = "allTasks" });
}
};
try
{
realm = await Realm.GetInstanceAsync(config);
}
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
}

在上面的示例中,代码显示了如何通过调用GetInstanceAsync()异步打开 Realm。 您还可以通过调用 GetInstance() 方法 同步 打开 Realm:

var synchronousRealm = Realm.GetInstance(config);

用户完成身份验证后, User对象将持续保留在设备上,直到用户注销。 这允许您的应用检索现有用户并在离线状态下打开同步域。一旦设备重新连接到您的应用,SDK 将同步离线时发生的更改。

以下代码演示如何检查是否存在现有的User对象。 如果未找到,则使用上文概述的过程来获取用户。 如果设备已有user ,则会与该用户一起打开同步 Realm:

var app = App.Create("myRealmAppId");
Realms.Sync.User user;
FlexibleSyncConfiguration config;
Realm realm;
if (app.CurrentUser == null)
{
// App must be online for user to authenticate
user = await app.LogInAsync(Credentials.Anonymous());
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
}
else
{
// This works whether online or offline
// It requires a user to have been previously authenticated
user = app.CurrentUser;
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
}

为了精细控制应用程序连接,您可以在 AppConfiguration 对象上设置 SyncTimeoutOptions 。您可以设置以下同步超时属性:

  • ConnectTimeout:完全建立连接所需的时间。

  • ConnectionLingerTime:放弃所有会话后保持连接打开的时间。

  • PingKeepAlivePeriod:每个 heartbeat 网络探测(ping)消息之间的时间量

  • PongKeepAliveTimeout:在断定连接已断开之前等待心跳网络探测(ping)响应的时间。

  • FastReconnectLimit:自上一个连接丢失以来,新连接被视为“快速重新连接”的时间量。

AppConfiguration configuration = new AppConfiguration("myRealmAppId")
{
SyncTimeoutOptions = new SyncTimeoutOptions()
{
ConnectTimeout = TimeSpan.FromMinutes(2),
ConnectionLingerTime = TimeSpan.FromSeconds(30),
PingKeepAlivePeriod = TimeSpan.FromMinutes(1),
PongKeepAliveTimeout = TimeSpan.FromMinutes(1),
FastReconnectLimit = TimeSpan.FromMinutes(1),
},
};

Realm 实例实现IDisposable以确保释放原生资源。您应该在使用 Realm 对象后立即对其进行处理,尤其是在后台线程中。 最简单的方法是使用using语句声明 Realm 对象,或在using (...)语句中包装与 Realm 交互的代码:

config = new PartitionSyncConfiguration("myPart", user);
using (var realm = Realm.GetInstance(config))
{
var allItems = realm.All<Item>();
}

如果您需要在单个方法之外共享 Realm 对象,请务必通过调用Dispose()方法来管理其状态:

realm.Dispose();

注意

作为一般规则,您应该仅在后台线程上处置 Realm,因为处置 Realm 会使与该实例关联的所有对象失效。 例如,如果您在主线程上对 Realm 对象进行数据绑定,则不应调用Dispose()

默认情况下,所有RealmObject类都存储在一个 Realm 中。 在某些情况下,您可能希望限制存储的类,这可以使用RealmConfiguration对象的Schema属性来实现。 以下代码演示了如何指定要存储在 Realm 中的两个类:

var config = new RealmConfiguration()
{
Schema = new Type[]
{
typeof(AClassWorthStoring),
typeof(AnotherClassWorthStoring)
}
};

后退

为应用添加同步功能

来年

写入同步 Realm - .NET SDK