简介
越来越多的Microsoft? Windows? Powered Pocket PC开始连接起来,为分布式应用程序带来了新的可能性 即使很多Web应用程序对这些设备时可用的,还是经常会有对离线操作支持的需要。 在企业环境中为了保持信息的一致性,离线应用程序需要与back-office 系统同步数据。 让我们从一些结构基本原理开始。
在现代的应用程序设计中,多层式模式通常是作为规则而非例外。 在服务器上我们越来越习惯于分离的用户服务(通常是演示)、企业服务和数据服务。 通过使用像Microsoft Visual Studio .NET 2003这样支持移动设备开发的工具,相同的模式可以被应用到移动应用程序 就“Sometimes Off-line”的应用程序而言,有一个应用程序运行在无服务器连接的工作设备上。 这一应用程序必须有多层式设计以获得与服务器端应用程序相同的好处(基于组件的、可重用性、可维护性等等)。 图1是对一个可能的分布式设计的高级别概述的阐释。
图 1:设备和服务器中的应用程序层
使用诸如Mobile Web Development with ASP.NET这类的技术,移动应用程序可以在服务器上完全实现。 然后,客户端只使用内置的浏览器来访问应用程序。 如果需要支持离线功能,应用程序就要运行在设备本身上了。 与此相关的技术是 Smart Device Programmability和Microsoft .NET框架压缩版。
返回页首
同步策略
通常,分布式应用程序需要连接到一台服务器上以得到使命关键信息;而且因为“始终连接”设备的梦想距离现实太遥远,也经常有支持离线操作的需要。 因此,数据需要在设备本地维护,然后再与服务器同步。 对于与服务器同步离线设备数据来说,最令人感兴趣的选项是数据库同步和应用程序同步。 图2阐释了两个选项概念上的概述。
图2:数据库与应用程序同步
数据库同步是一种保持设备和服务器数据最新的非常有效的方法。 只有有必要的信息才被传输而且甚至以压缩模式传输。 但是,如果在同步中涉及到逻辑,那么需要有更程序化的方法来解决问题。 让我们把这叫做“应用程序同步”,这意谓着在同步时设备上的业务逻辑层连接到服务器上的业务逻辑。 在许多真实的应用程序中,结合这两种选项的设计会是最好的设计。
返回页首
数据库同步
如果设备上的数据是在SQL Server? for Windows CE (SQLCE)数据库上维护的,那么在.NET框架压缩版中支持与SQL Server数据库同步这些数据。 这种功能是在System.Data.SqlServerCe名称空间的SqlCeReplication类中实现的。 可以采用的两条路径是远程数据访问(Remote Data Access, RDA)和合并复制。 RDA是推拉表数据出入设备的轻量方法。 另一方面,合并复制被用于更高级的同步。请阅读文章 SQL Server 2000 Windows CE Edition and the .NET Compact Framework(英文)中的更多信息,有关合并复制的详细信息,请参阅 Programming Merge Replication with the Microsoft .NET Compact Framework(英文)。
当数据同步中不涉及太多逻辑时,数据库同步是很有趣的。 这是一个非常快的选项 — 尤其当是大量数据需要传输时。 它要求设备数据被存储在SQLCE数据库中。
如图2中用虚线标明的,如果只涉及客户端同步逻辑,使用System.Data.SqlClient名称空间来访问服务器数据库也是可能的。
返回页首
应用程序同步
在很多情况下,数据同步涉及到的逻辑需要有比数据库同步许可更复杂的机制。 Application synchronization is much like application integrationtwo applications that connect to exchange data.应用程序同步很像应用程序集成 — 两个应用程序连接起来以交换数据。 在.NET 框架压缩版中,使其发生的最明显的构造是通过XML Web服务的使用。 使用Web服务,设备可以以一种松耦合方法并基于诸如XML和HTTP等标准连接到服务器端逻辑。 在.NET框架压缩版中对Web服务的支持可以在System.Web.Services名称空间中找到。
如果需要更高级的同步方案,应用程序同步是应该选择的。 让我们看一个实现示例。
返回页首
Reading Anyplace示例
Reading Anyplace示例应用程序展示了一个检查员怎样离线记录计量器读数然后将其与服务器同步。 这个应用程序由一个窗体组成,如图3所示。
图3:Reading Anyplace示例
可以输入计量器ID和位置,当点击Record按钮时,记录被添加到列表中。 每一个新记录被标注为“New”。 如果同一个计量器再次被使用,那么相应的记录就会更新。 当Synchronize按钮被点击时,每一个记录都会通过Web服务送到服务器。 接着响应会在列表中的Remark列中更新。 一个正确的读数被标注为“OK”,同时不正确的读数也会被标注,说明确认的错误(如图3中ID为1234的计量器被标注“太高!”)。 点击Clean up按钮清除列表中所有标注设为“OK”的记录。
这里的逻辑是这样的,直到设备数据与服务器同步之后,计量器读数确认才能发生。 由于应用程序同步设计,这样的反馈是可能的,而且如果用数据库同步这将更难以实现。
返回页首
代码演练
因为这个示例的中心不是要展示一个完整的服务器实现,服务器端Web服务实现看起来仅仅像这样:
[WebMethod]
public string SyncReading(string ID, int Position)
{
if (ID == "1234" && Position > 1000)
return "Too high!";
else
return "OK";
}
示例Web服务是硬编码的,只检查ID为1234的计量器在1000以上的计量位置。在实际方案中,可能应该用来自存储在服务器数据库中的以往读数的位置预估来作一个比较。 同样,如果来自其他检查员的以往读数被提供给客户端,这个示例在服务器端将需要更多的同步逻辑。
在客户端,当为这个Web服务创建一个Web引用时,Synchronization按钮的代码看起来是这样:
Cursor.Current = Cursors.WaitCursor;
Reading.Server.Sync sync = new Reading.Server.Sync();
try
{
foreach (ListViewItem lvi in lvwItems.Items)
if (lvi.SubItems[2].Text == "New")
lvi.SubItems[2].Text = sync.SyncReading(lvi.Text,
Convert.ToInt32(lvi.SubItems[1].Text));
}
catch (Exception ex)
{
MessageBox.Show("Could not call Web Service!", this.Text);
}
finally
{
Cursor.Current = Cursors.Default;
}
当等待光标显示时,Web服务对象(sync)被创建。 然后,在ListView中的每一个新记录(标注为“New”)被送到Web服务方法(SyncReading),ListView中的Remarks列由Web服务响应更新。 如果有什么错误,会显示一个消息框,无论发生了什么,光标都被还原。
在本示例中,本地数据只在ListView控件中维护,当示例应用程序结束时,数据就丢失了。 在实际方案中,这些数据可能被传输到一个DataSet并作为一个XML文件或在一个SQLCE数据库中存储。
返回页首
小结
当有诸如服务器端确认之类的逻辑的需要时,应用程序同步是在“sometimes off-line”应用程序中实现同步的优先选择。 Web服务是实现应用程序同步的平滑方法,因为这样能允许客户端逻辑连接到服务器端逻辑。 因此,对于从一个基于.NET框架压缩版的Pocket PC应用程序调用Web服务来说,本机支持是真正有价值的。