Azure 移动应用中的脱机数据同步Offline Data Sync in Azure Mobile Apps

什么是脱机数据同步?What is offline data sync?

脱机数据同步是 Azure 移动应用的客户端和服务器 SDK 功能,可让开发人员创建不需要网络连接就能正常运行的应用。Offline data sync is a client and server SDK feature of Azure Mobile Apps that makes it easy for developers to create apps that are functional without a network connection.

应用处于脱机模式时,仍可创建和修改数据,并且数据会保存到本地存储。When your app is in offline mode, you can still create and modify data, which are saved to a local store. 当应用重新联机时,即可将本地更改与 Azure 移动应用后端同步。When the app is back online, it can synchronize local changes with your Azure Mobile App backend. 此功能还支持冲突检测(当同一条记录同时在客户端和后端发生更改时,即会发生冲突)。The feature also includes support for detecting conflicts when the same record is changed on both the client and the backend. 可以在服务器或客户端上处理冲突。Conflicts can then be handled either on the server or the client.

脱机同步具有几个优点:Offline sync has several benefits:

  • 通过缓存在设备上的本地服务器数据来提高应用程序响应能力Improve app responsiveness by caching server data locally on the device
  • 创建当网络出问题时仍可使用的稳健应用Create robust apps that remain useful when there are network issues
  • 允许最终用户创建和修改数据,甚至在没有网络访问权限,并且支持方案具有很少或没有连接时也是如此Allow end users to create and modify data even when there is no network access, supporting scenarios with little or no connectivity
  • 跨多个设备同步数据和同一个记录修改由两个设备时检测冲突Sync data across multiple devices and detect conflicts when the same record is modified by two devices
  • 在高延迟状态下或者在流量计费网络中限制网络使用Limit network use on high-latency or metered networks

以下教程说明如何使用 Azure 移动应用将脱机同步添加到移动客户端:The following tutorials show how to add offline sync to your mobile clients using Azure Mobile Apps:

什么是同步表?What is a sync table?

为了访问“/tables”终结点,Azure 移动客户端 SDK 提供 IMobileServiceTable(.NET 客户端 SDK)或 MSTable(iOS 客户端)等接口。To access the "/tables" endpoint, the Azure Mobile client SDKs provide interfaces such as IMobileServiceTable (.NET client SDK) or MSTable (iOS client). 这些 API 直接连接到 Azure 移动应用后端,如果客户端设备没有网络连接,则会失败。These APIs connect directly to the Azure Mobile App backend and fail if the client device does not have a network connection.

若要支持脱机使用,应用应该改用同步表 API,例如 IMobileServiceSyncTable(.NET 客户端 SDK)或 MSSyncTable(iOS 客户端)。To support offline use, your app should instead use the sync table APIs, such as IMobileServiceSyncTable (.NET client SDK) or MSSyncTable (iOS client). 所有相同的 CRUD 操作(创建、读取、更新、删除)都适用于同步表 API,不过它们现在从本地存储 读取或向其写入数据。All the same CRUD operations (Create, Read, Update, Delete) work against sync table APIs, except now they read from or write to a local store. 在执行任何同步表操作之前,必须先初始化本地存储。Before any sync table operations can be performed, the local store must be initialized.

什么是本地存储?What is a local store?

本地存储是客户端设备上的数据持久层。A local store is the data persistence layer on the client device. Azure 移动应用客户端 SDK 提供默认的本地存储实现。The Azure Mobile Apps client SDKs provide a default local store implementation. 在 Windows、Xamarin 和 Android 上,它基于 SQLite。On Windows, Xamarin and Android, it is based on SQLite. 在 iOS 上,它基于核心数据。On iOS, it is based on Core Data.

若要在 Windows Phone 或 Microsoft Store 中使用基于 SQLite 的实现,需要安装 SQLite 扩展。To use the SQLite-based implementation on Windows Phone or Microsoft Store, you need to install a SQLite extension. 有关详细信息,请参阅通用 Windows 平台:启用脱机同步。Android 和 iOS 设备的操作系统本身包含 SQLite 版本,因此不需要引用自己的 SQLite 版本。For more information, see Universal Windows Platform: Enable offline sync. Android and iOS ship with a version of SQLite in the device operating system itself, so it is not necessary to reference your own version of SQLite.

开发人员也可以实现自己的本地存储。Developers can also implement their own local store. 例如,如果希望将数据以加密格式存储在移动客户端上,可以定义使用 SQLCipher 进行加密的本地存储。For instance, if you wish to store data in an encrypted format on the mobile client, you can define a local store that uses SQLCipher for encryption.

什么是同步上下文?What is a sync context?

同步上下文与移动客户端对象(例如 IMobileServiceClientMSClient)关联,并跟踪对同步表所做的更改。A sync context is associated with a mobile client object (such as IMobileServiceClient or MSClient) and tracks changes that are made with sync tables. 同步上下文维护操作队列 ,其中保留了 CUD 操作(Create、Update、Delete)的顺序列表,该列表稍后发送到服务器。The sync context maintains an operation queue, which keeps an ordered list of CUD operations (Create, Update, Delete) that is later sent to the server.

本地存储使用初始化方法(例如 .NET 客户端 SDK 中的 IMobileServicesSyncContext.InitializeAsync(localstore))来与同步上下文关联。A local store is associated with the sync context using an initialize method such as IMobileServicesSyncContext.InitializeAsync(localstore) in the .NET client SDK.

脱机同步的工作原理How offline synchronization works

使用同步表时,客户端代码控制本地更改与 Azure 移动应用后端同步的时机。When using sync tables, your client code controls when local changes are synchronized with an Azure Mobile App backend. 在发生 推送 本地更改的调用之前,不会向后端发送任何内容。Nothing is sent to the backend until there is a call to push local changes. 同样,仅当发生了 提取 数据的调用时,才在本地存储中填充新数据。Similarly, the local store is populated with new data only when there is a call to pull data.

  • 推送:推送是对同步上下文的操作,发送自上一次推送之后的所有 CUD 更改。Push: Push is an operation on the sync context and sends all CUD changes since the last push. 请注意,无法做到只发送单个表的更改,否则这些操作可能以无序发送。Note that it is not possible to send only an individual table's changes, because otherwise operations could be sent out of order. 推送对 Azure 移动应用后端执行一系列 REST 调用,而这会修改服务器数据库。Push executes a series of REST calls to your Azure Mobile App backend, which in turn modifies your server database.

  • 拉取:拉取按表执行并可使用查询进行自定义,以便只检索服务器数据的子集。Pull: Pull is performed on a per-table basis and can be customized with a query to retrieve only a subset of the server data. 然后,Azure 移动客户端 SDK 会将最终数据插入本地存储。The Azure Mobile client SDKs then insert the resulting data into the local store.

  • 隐式推送:如果针对包含挂起本地更新的表执行拉取,则拉取操作先对同步上下文执行 push()Implicit Pushes: If a pull is executed against a table that has pending local updates, the pull first executes a push() on the sync context. 此推送有助于最大程度减少已排队的更改与服务器中新数据之间的冲突。This push helps minimize conflicts between changes that are already queued and new data from the server.

  • 增量同步 :拉取操作的第一个参数是 query name ,此参数只在客户端上使用。Incremental Sync: the first parameter to the pull operation is a query name that is used only on the client. 如果使用非 null 查询名称,Azure Mobile SDK 将执行增量同步 。每次拉取操作返回结果集时,该结果集中最新的 updatedAt 时间戳将存储在 SDK 本地系统表中。If you use a non-null query name, the Azure Mobile SDK performs an incremental sync. Each time a pull operation returns a set of results, the latest updatedAt timestamp from that result set is stored in the SDK local system tables. 后续拉取操作只检索该时间戳以后的记录。Subsequent pull operations retrieve only records after that timestamp.

    若要使用增量同步,服务器必须返回有意义的 updatedAt 值,并且必须支持按此字段排序。To use incremental sync, your server must return meaningful updatedAt values and must also support sorting by this field. 但是,由于 SDK 在 updatedAt 字段中添加了自身的排序,因此无法使用本身具有 orderBy 子句的拉取查询。However, since the SDK adds its own sort on the updatedAt field, you cannot use a pull query that has its own orderBy clause.

    查询名称可以是所选的任何字符串,但是对应用中的每个逻辑查询必须保持唯一。The query name can be any string you choose, but it must be unique for each logical query in your app. 否则,不同的拉取操作可能覆盖相同的增量同步时间戳,查询可能因此返回错误的结果。Otherwise, different pull operations could overwrite the same incremental sync timestamp and your queries can return incorrect results.

    如果查询具有参数,创建唯一查询名称的方法之一是包含该参数值。If the query has a parameter, one way to create a unique query name is to incorporate the parameter value. 例如,如果要按 userid 筛选,可以使用如下所示的查询名称(在 C# 中):For instance, if you are filtering on userid, your query name could be as follows (in C#):

      await todoTable.PullAsync("todoItems" + userid,
          syncTable.Where(u => u.UserId == userid));
    

    如果想要选择退出增量同步,请将 null 作为查询 ID 传递。If you want to opt out of incremental sync, pass null as the query ID. 在此情况下,在对 PullAsync 的每次调用中将检索所有记录,这可能会降低效率。In this case, all records are retrieved on every call to PullAsync, which is potentially inefficient.

  • 清除:可以使用 IMobileServiceSyncTable.PurgeAsync 清除本地存储的内容。Purging: You can clear the contents of the local store using IMobileServiceSyncTable.PurgeAsync. 如果客户端数据库包含陈旧的数据,或者需要丢弃所有挂起的更改,可能需要执行清除操作。Purging may be necessary if you have stale data in the client database, or if you wish to discard all pending changes.

    清除操作会从本地存储中清除表。A purge clears a table from the local store. 如果有操作正在等待与服务器数据库的同步,除非设置了 force purge 参数,否则清除将引发异常。If there are operations awaiting synchronization with the server database, the purge throws an exception unless the force purge parameter is set.

    客户端包含陈旧数据的示例:假设在“待办事项列表”示例中,Device1 只拉取未完成的项。As an example of stale data on the client, suppose in the "todo list" example, Device1 only pulls items that are not completed. “购买牛奶”待办事项由其他设备在服务器上标记为已完成。A todoitem "Buy milk" is marked completed on the server by another device. 但是,Device1 在本地存储中仍有“购买牛奶”待办事项,因为它只拉取未标记为已完成的项。However, Device1 still has the "Buy milk" todoitem in local store because it is only pulling items that are not marked complete. 清除操作会清除这条陈旧项。A purge clears this stale item.

后续步骤Next steps