UML软件工程组织

“间断离线”的Microsoft .NET 精简框架应用程序设计
作者: ZDNet China
Thursday, October 16 2003 2:18 PM
适用于:

Microsoft® Visual Studio® .NET 2003
Microsoft .NET Compact Framework
Microsoft Windows® Powered Pocket PC

概述:通过理解可选的设计方法,学习怎样使“间断离线”的应用程序能够与服务器同步。本文还包含使用Web Service来实现同步的示例应用程序。

在微软下载中心(Microsoft Download Center)下载例子程序Sometimes_offline.exe

介绍

随着越来越多的Microsoft® Windows® Powered Pocket PC可以进行连接,分布式应用程序出现了新的机会。但是即使这些设备能够访问很多的Web应用程序,它们最常见的需求还是对离线操作的支持。要在合作的环境中保持信息的一致,离线应用程序需要与后备系统同步。我们先从一些基本结构谈起。

在现代应用程序设计中,多层模式占绝大多数。在服务器上我们逐渐习惯于独立使用用户服务(通常是表示)、业务服务和数据服务。利用象Microsoft Visual Studio .NET 2003这样支持移动设备开发的工具,可以将这种模式应用于移动应用程序。在考虑“间断离线”应用时,设备上的程序在不与服务器连接时也需要运行。应用程序应该具有多层设计以获得与服务器端程序相同的优势(组件化、可重用性、可维护性等等)。图1是一种分布式设计的高度抽象。

图1 设备和服务器上应用程序的层次

移动应用程序可以完全在服务器端使用Mobile Web Development with ASP.NET这样的技术来实现。客户端仅使用内建的浏览器来访问应用程序。如果需要支持离线功能,则应用程序需要能独立在设备上运行。与此相关的技术是Smart Device ProgrammabilityMicrosoft .NET Compact Framework

同步策略

一个分布式应用程序通常需要连接服务器以获取关键信息,由于设备“总是连接”的梦想与实际相差太远,因此经常需要对离线操作的支持。也就是说,数据需要在设备本地维护,并且要和服务器同步。离线设备数据与服务器同步问题中最令人关注的选择是数据库同步和应用程序同步。图2描绘了两者的概念。

图2 数据库同步和应用程序同步

数据库同步是保持设备和服务器上数据一致的一种非常有效率的方法。只有必须的信息被传输甚至是压缩传输。但是,如果在同步过程中包含了某些逻辑,则需要有更具有编程性的方法来解决这个问题。我们叫它“应用程序同步”,即在进行同步时设备的业务逻辑层与服务的业务逻辑层要连接。在很多实际的程序中,将这两种方法结合起来效果更好。

数据库同步

如果设备上的数据是在SQL Server™ for Windows CE (SQLCE)数据库中维护的,那么在.NET Compact Framework中提供了其与SQL Server数据库同步的支持。这个功能是在System.Data.SqlServerCe命名空间中的SqlCeReplication类中实现的。采取的两种途径是远程数据访问(Remote Data Access,RDA)和合并复制(Merge Replication)。RDA是从设备交换数据的轻量级方法。相反,Merge Replication则用于更高级的同步。

在数据同步中逻辑不多的情况下,数据库同步很好用。它是非常快的选择——特别是在数据需要通过传输而载入的情况下。它还需要设备数据存储在SQLCE数据库中。

如同图2中虚线指出的,如果只包含客户端同步逻辑,那么也可以使用System.Data.SqlClient命名空间来访问服务器数据库。

应用程序同步

在很多情况下数据的同步包含复杂的逻辑,超出了数据库同步允许的范围。应用程序同步与应用程序集成非常类似——两个应用程序连接来交换数据。.NET Compact Framework中实现它的最明显的结构XML Web服务。使用Web服务,设备能够以一种松散连接的方式与服务器端逻辑相连,并以XML和HTTP这样的标准为基础。.NET Compact Framework中对于Web服务的支持包含在System.Web.Serveces命名空间中。

应用程序同步适用于更加高级的同步场合。我们来看一个实现的例子。

Reading Anyplace样例

Reading Anyplace示例应用程序示范了巡检员如何离线记录仪表读数然后于服务器同步。程序由一个窗体组成,如图3所示。

图3 Reading Anyplace样例

输入仪表ID和读数,当按下Record按钮时,记录就被添加到列表中。每个记录都被标识为“New”。如果又用到了相同的仪表ID,则相应的记录就被更新。当按下Synchronize按钮时,每条记录都使用Web服务发送到服务器。然后服务器返回结果更新Remark列。正常的记录的回应是“OK”,不正确的结果的回应解释其错误原因(比如图3中ID为1234的仪表的结果为“Too high”)。按下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 Reference时,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中的Remark列用Web服务的回应结果来更新。如果中间出错,会显示消息框,而不论发生什么,鼠标指针都还原。

在这个例子中,本地数据仅在ListView控件中维护,当程序结束时,数据就丢失了。在实际应用中,数据可能被转移到DataSet中并作为XML或SQLCE数据库存储。

总结

在需要某些逻辑如服务器端验证时,应用程序同步是实现“间断离线”程序首选的方法。由于Web服务允许客户端逻辑与服务器端逻辑相连接,它可以光滑地实现应用程序同步。因此,能够从一个基于.NET Compact Framework的Pocket PC应用程序中调用Web服务,这样的本地支持是真正具有价值的。


 

版权所有:UML软件工程组织