第 3 章 — 建立连接
按照定义,智能客户端需要连接到其他资源并与这些资源进行通讯,并且构成分布式应用程序的一部分。这些资源可以是客户端进程或组件,也可以是网络资源,如
Web 服务。
本章分析智能客户端与其他资源之间的通讯的性质。本章将考察可用来连接和使用其他进程、组件或远程服务中的资源的不同技术,并且讨论如何对它们进行取舍。最后,本章将分析如何最好地设计您的智能客户端以连接到资源。
松耦合系统和紧耦合系统
客户端应用程序可以用不同的方式连接和使用其他进程(包括本地进程和网络进程)中的组件和服务。按照服务与客户端之间存在多少耦合性对不同的方法进行分类是很有用的。
耦合性是指组件(在分布式系统中)互相依赖的程度。客户端与它们同其进行通讯的服务之间耦合的性质可能影响智能客户端设计的许多方面,包括互操作性、脱机功能、网络通讯性能、部署以及维护注意事项。
紧耦合系统通常提供直接的对象到对象通讯,并且客户端上的对象对远程对象具有详细的了解。这种紧耦合性可以防止对客户端或服务器进行单独更新。因为紧耦合系统涉及直接的对象到对象通讯,所以对象通常比在松耦合系统中更为频繁地交互,这样,如果两个对象位于不同的计算机上并且由网络连接分隔,则可能导致性能和延迟问题。
松耦合系统通常是基于消息的系统,此时客户端和远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。只要消息符合协商的架构,则客户端或服务的实现就可以根据需要进行更改,而不必担心会破坏对方。
松耦合通讯机制提供了紧耦合机制所没有的许多优点,并且它们有助于降低客户端和远程服务之间的依赖性。但是,紧耦合性通常可以提供性能好处,便于在客户端和服务之间进行更为紧密的集成(这在存在安全性和事务处理要求时,可能是必需的)。
所有与远程服务或组件通讯的分布式客户端都具有某种程度的耦合性。您需要了解各种松耦合方法和紧耦合方法具有的不同特征,以便为您的应用程序选择合适程度的耦合性。
通讯选项
当您设计智能客户端应用程序时,您可以从多种将其连接到其他资源的方法中进行选择,这些方法包括:
Microsoft_ .NET Enterprise Services。
Microsoft .NET remoting。
Microsoft Windows_ 消息队列(也称为 MSMQ)。
Web 服务。
.NET Enterprise Services
您可以使用 .NET Enterprise Services 提供对托管代码组件和应用程序的 COM+ 服务基础结构的访问。.NET
组件依赖 COM+ 为其提供许多组件服务,如:
Transaction support.
Role-based security.
Loosely coupled events.
Object pooling.
Queued components.
Just-in-time activation.
使用 COM+ 服务的 .NET 组件称为服务组件。因为您的服务组件以 COM+应用程序为宿主,所以它们必须可供该应用程序访问。这就为服务组件带来了一些注册和配置要求:
程序集必须从 System.EnterpriseServices 命名空间中的 ServicedComponent
类派生。
程序集必须是强命名的。
程序集必须在 Microsoft Windows 注册表中注册。
必须将程序集的类型库定义注册和安装到特定的 COM+应用程序中。
如果程序集包含被配置为进程外应用程序的服务组件,则应该将相应的程序集放到全局程序集缓存中。如果程序集包含被配置为进程内库的服务组件,则不必将其放到全局程序集缓存中,除非它们位于与应用程序不同的目录中。如果您以这种方式部署同一版本服务组件的多个副本,则
COM+ 目录包含该组件的所有实例的全局配置;您无法逐个副本地对它们进行配置。
消息队列
借助于 Microsoft Windows 消息队列,您可以很容易地通过发送和接收消息,快速而可靠地与应用程序通讯。消息处理为您提供了有保证的消息传递以及执行许多业务过程的可靠方式。消息队列提供了一种您可以在智能客户端应用程序内使用的松耦合通讯机制。消息队列具有下列功能:
有保证的消息传递。消息队列通过将消息存储在队列中直到其可以传递,保证了即使远程系统失败或不存在,消息也能够传递。因此,与组件之间的直接调用相比,消息受失败的影响的程度要小得多。
消息优先级化。更为紧急或重要的消息可以在不太重要的消息之前收到,从而有助于保证为关键应用程序提供足够的响应时间。
注 您只能为非事务性消息设置消息优先级。
脱机功能。如果消息因为客户端脱机而无法传递,则会将它们存储在待发队列中,并且在客户端重新联机时自动传递它们。用户在无法访问目标队列时可以继续执行操作。同时,其他操作可以像消息已被处理一样继续执行,因为当网络连接还原时可以保证传递消息。
事务性消息处理。您将消息作为事务的一部分发送。这样,您就可以发送多个相关消息,或者将您的应用程序设计为参与分布式事务,并且确保所有消息都按顺序传递并且只传递一次。如果事务内发生任何错误,则整个事务都将被取消,并且不会发送任何消息。
安全性。MessageQueue 组件所基于的消息队列技术使用 Windows 安全性来确保访问控制的安全、提供审核以及对您的组件发送和接收的消息进行加密和身份验证。可以在网络上对消息队列消息进行加密,以使其不会被包嗅探器截获。您还可以禁止队列接收未加密的消息。
使用消息队列的应用程序可以通过使用 System.Messaging 命名空间中的类来发送消息以及从队列中读取消息。Message
类用于封装要发送到队列的消息,而 MessageQueue 类提供了对特定队列及其属性的访问。
您需要在任何使用消息队列的计算机上安装和配置它。Windows 桌面操作系统和 Microsoft Windows
CE .NET 都可以使用消息队列,从而使您可以在移动设备(如 Pocket PC 设备)上使用它。
要与提供基于消息的访问的服务交互,消息队列是一种很好的选择。您可以使用消息队列与其他装有消息队列的系统通讯。尽管您可以使用连接工具包与其他消息处理系统(如
IBM 的 MQSeries)通讯,但与其他系统之间的互操作性是有限的。
设计连接的智能客户端应用程序
当您设计您的智能客户端时,您应该考虑一些建议,包括:
使用粗粒度的、封装的消息。
避免分布式 ACID 事务。
避免在网络中发送数据集。
将大型数据集分解。
将您的 Web 服务和程序集版本化。
使用粗粒度的、封装的消息
分布式网络调用是代价高昂的操作。您不应该使用与设计本地接口相同的细粒度方法来设计您的外部接口。要避免消息之间存在消息依赖性,比较好的做法是将接口方法生成为独立函数。这样做可以使您不必编写复杂的跟踪协调代码来处理依赖于其他消息成功完成的消息的失败。
避免分布式 ACID 事务
分布式 ACID(原子、一致、独立、持久)事务是资源密集型的,伴随大量网络通信以及挂起本地事务上的大量相互依赖的系统锁。如果您的智能客户端或服务正在等待答复,并且在收到该答复之前无法继续工作,则分布式
ACID 事务可能阻止业务过程。
如果您的智能客户端可能不加警告就切换到脱机模式,则分布式 ACID 事务的问题将会恶化。在此情况下,客户端可能对数据加锁,并且在可以在服务器释放该锁之前进入脱机模式。
如果您无法通过将接口分解为单独的不连续消息来避免消息依赖性,则您具有许多处理事务的选项,并且还可以避免分布式
ACID 事务:
将紧耦合消息提交给服务器,并且让事务协调器(如 Microsoft BizTalk? Server)来处理消息依赖性。
自己在客户端或服务器上编写事务补偿代码。使用相应的通讯协议,以便服务器可以用来决定何时启动事务,以及如何通知客户端要完整处理的事务成功完成或失败。
避免在网络中发送数据集
数据集可能太大、太详细,因而无法用作在多个层之间发送数据的通讯有效负载机制。取而代之,您应该使用数据传输对象
(DTO) 来减少发送到外部接口的消息有效负载。对于数据更改,您应该考虑只发送已更改的数据,而不是发送整个数据集。
有关 DTO 的详细信息,请参阅第 2 章:处理数据。
将大型数据集分解
如果您试图同时显示大型数据集的所有内容,则它们可能在客户端导致性能问题。因此,您应该将它们分解为较小的数据集。以这种方式分解数据称为分页。例如,与显示电话目录的全部内容不同,您可以选择一次显示一页(例如,每屏按字母顺序显示
20 个记录)。如果您将客户端设计为使用分页,则应该确保对用户界面进行相应的设计,以便使用户可以容易地在各个页之间导航。
这一分解大型数据集的概念还适用于通过网络与服务器进行的通讯。如果您可以将数据分解为可管理的数据块,则您随后可以按照需要加载所需的数据,这种技术称为惰性加载。在电话目录示例中,只有当前操作需要的数据将被加载,从而减小了对应用程序和网络的影响,并且可能使二者的响应更为迅速。
要改善用户体验,可以在对即将到来的用户请求进行预测的基础上,使用附加线程执行后台处理以及与服务之间的通讯。
尽管对惰性加载的支持可能是智能客户端应用程序设计的重要方面,但您应该记住应用程序的脱机要求。通过网络传输的惰性加载数据可能会妨碍应用程序像您希望的那样脱机工作。
将您的 Web 服务和程序集版本化
当您将新版本的智能客户端软件发布到客户端或者对该软件进行升级时,应该创建新版本的程序集。如果您使用版本化的程序集,并且如果您将服务器服务设计为支持向后兼容接口,则可以支持多个版本的客户端软件。在发布新版本的
Web 服务时,您应该通过规范的命名约定来区分它们。可以改变各个版本的命名空间,以便它们包含日期信息,从而能够清楚正在与哪个版本的
Web 服务客户端通讯。
|