贝贝花花包包店,精品555皮具,钱夹,皮夹

字体: | 推荐给好友 上一篇 | 下一篇

ACE技术论文集-第9章连接和初始化通信服务的对象创建模式

发布: 2008-6-13 14:37 | 作者: Prashant Jain and D | 来源: 转载 | 查看: 334次

 
9.9.2 用于Gateway的具体组件
图9-11演示Concrete Connector和Concrete Service Handler组件是怎样在假想的Gateway配置中构造的。该图中的Connector组件与图9-9中的Acceptor组件是互补的。
 
 
图9-11 网关的Connector参与者的结构
 
用于Gateway路由的服务处理器:如下所示的Status Router、Buld Data Router和Command Router类将它们从源Peer接收到的数据路由到一或多个目的Peer。因为这些Concrete Service Handler类继承自Service Handler,它们可以被Connector主动地连接和初始化。
为演示接受器-连接器模式的灵活性,Service Handler中的每个open例程实现不同的并发策略。特别地,当Status Router被启用时,它运行在单独的线程中;Bulk Data Router作为单独的进程运行;而Command Router运行在与Initiation Dispatcher相同的线程中,后者为Connector工厂进行连接完成事件的多路分离。就如同Acceptor一样,注意这些并发策略的变动并不会影响Connector的实现,它是通用的,因而也是高度灵活和可复用的。
我们从定义一个Service Handler开始,它为基于socket的数据传输而定制:
 
typedef Service_Handler PEER_ROUTER;
 
该类构成所有后续路由服务的基础。例如,Status Router类路由状态数据到Peer,或路由来自Peer的数据:
 
class Status_Router : public PEER_ROUTER
{
public:
// Activate router in separate thread.
virtual int open (void)
{
// Thread::spawn requires a pointer to a
// static method as the thread entry point).
Thread::spawn (&Status_Router::service_run, this);
}
 
// Static entry point into thread, which blocks
// on the handle_event() call in its own thread.
static void *service_run (Status_Router *this_)
{
// This method can block since it
// runs in its own thread.
while (this_->handle_event () != -1)
continue;
}
 
// Receive and route status data from/to Peers.
virtual int handle_event (void)
{
char buf[MAX_STATUS_DATA];
peer_stream_.recv (buf, sizeof buf);
 
// Routing takes place here...
}
 
// ...
};
 
PEER ROUTER可被子类化,以生成用于路由大块数据和命令具体的服务处理器。例如,Bulk Data Router路由数据到Peer,或路由来自Peer的数据:
 
class Bulk_Data_Router : public PEER_ROUTER
{
public:
// Activates router in separate process.
virtual int open (void)
{
if (fork () == 0) // In child process.
// This method can block since it
// runs in its own process.
while (handle_event () != -1)
continue;
 
// ...
}
 
// Receive and route bulk data from/to Peers.
virtual int handle_event (void)
{
char buf[MAX_BULK_DATA];
peer_stream_.recv (buf, sizeof buf);
 
// Routing takes place here...
}
};
 
Command Router类路由命令数据到Peer,或路由来自Peer的命令数据:
 
class Command_Router : public PEER_ROUTER
{
public:
// Activates router in same thread as Connector.
virtual int open (void)
{
Initiation_Dispatcher::instance
()->register_handler (this, READ_MASK);
}
 
// Receive and route command data from/to Peers.
virtual int handle_event (void)
{
char buf[MAX_COMMAND_DATA];
 
// This method cannot block since it borrows the
// thread of control from the Initiation_Dispatcher.
peer_stream_.recv (buf, sizeof buf);
 
// Routing takes place here...
}
};
 
用于创建Peer Service Handler的接受器:下面的typedef定义为PEER ROUTER而定制的connector工厂:
 
typedef ConnectorPEER_CONNECTOR;
 
不像 Concrete Acceptor组件,我们只需要单个Concrete Connector。原因是每个Concrete Acceptor都被用作创建特定类型的Concrete Service Handler(比如Bulk Data Handler或Command Handler)的工厂。因此,必须预先知道全部的类型,从而使多种Concrete Acceptor类型成为必要。相反,传递给Connector的connect方法的Concrete Service Handler是在外部初始化的。因此,它们可以统一地被当作PEER ROUTER处理。
 
Gateway主函数:Gateway的主程序如下所示。get_peer_addrs函数创建Status、Bulk Data和Command Router,通过Gateway路由消息。该函数(它的实现没有给出)从配置文件或名字服务中读取Peer地址列表。每个Peer地址含有IP地址和端口号。一旦Router被初始化,上面定义的Connector工厂通过将ASYNC标志传递给connect方法来异步地发起所有连接。
 
// Main program for the Gateway.
 
// Obtain an STL vector of Status_Routers,
// Bulk_Data_Routers, and Command_Routers
// from a config file.
 
void get_peer_addrs (vector &peers);
 
int main (void)
{
// Connection factory for PEER_ROUTERS.
PEER_CONNECTOR peer_connector;
 
// A vector of PEER_ROUTERs that perform
// the Gateway’s routing services.
vector peers;
 
// Get vector of Peers to connect with.
get_peer_addrs (peers);
 
// Iterate through all the Routers and
// initiate connections asynchronously.
for (vector::iterator i = peers.begin ();
i != peers.end ();
i++)
{
PEER_ROUTER &peer = *i;
peer_connector.connect (peer,
peer.remote_addr (),
PEER_CONNECTOR::ASYNC);
}
 
// Loop forever handling connection completion
// events and routing data from Peers.
for (;;)
Initiation_Dispatcher::instance()->handle_events ();
 
/* NOTREACHED */
}
 
所有连接都被异步地调用。它们通过Connector的complete方法并发地完成,该方法在Initiation Dispatcher的事件循环中被回调。此事件循环还为Command Router对象多路分离和分派路由事件;该对象运行在Initiation Dispatcher的线程控制中。Status Router和Bulk Data Router分别执行在单独的线程和进程中。
图9-12演示在与Peer(如图9-10所示)的四个连接被建立、以及四个Concrete Service Handler被创建和启用后,Gateway中的组件之间的关系。该图演示到另一个Peer的四个连接,它们被Connector“拥有”,还没有完成。当所有Peer连接完全建立时,Gateway将路由并转发由Peer发送给它的消息。
 
 
图9-12 网关中的Connector组件的对象图
9.10 已知应用
 
接受器-连接器模式已被用于广泛的构架、工具包和系统中:
 
UNIX网络超级服务器:比如inetd[13]、listen[14]以及来自ASX构架[6]的Service Configurator(服务配置器)看守。这些超级服务器利用主Acceptor进程,在一组通信端口上侦听连接。每个端口都和与通信有关的服务(比如标准的Internet服务ftp、telnet、daytime和echo)相关联。接受器进程使inetd超级服务器的功能分解为两个分离的部分:一个用于建立连接,另一个用于接收和处理来自对端的的请求。当服务请求在被监控的端口上到达时,接受器进程接受请求,并分派适当的预登记的处理器来执行服务。
 
CORBA ORB许多CORBA实现中的ORB核心层使用接受器-连接器来在客户请求ORB服务时被动地初始化服务器对象实现。[17]描述接受器-连接器模式怎样被用于实现The ACE ORB(TAO)[18];TAO是CORBA一种实时实现。
 
WWW浏览器:像Netscape和Internet Explorer这样的WWW浏览器中的HTML解析组件使用connector组件的异步版本来建立与服务器的连接;这些服务器与HTML页面中嵌入的图像相关联。这样的行为是特别重要的,于是多个HTTP连接就可被异步地发起,以避免阻塞浏览器主事件循环。
 
Ericsson EOS呼叫中心管理系统:该系统使用接受器-连接器模式来使应用级呼叫中心管理器事件服务器[19]主动地与分布式中央管理系统中的被动的超级用户建立连接。
 
Spectrum项目:Spectrum项目的高速医学图像传输子系统[20]使用接受器-连接器模式来为存储大型医学图像被动地建立连接,并初始化应用服务。一旦连接被建立,应用就发送数兆字节的医学图像给图像仓库;或从图像仓库中进行接收。
 
ACE 构架:在本论文中描述的Service Handler、Connector和Acceptor类的实现在ACE面向对象网络编程构架[6]中作为可复用组件提供。
 
9.11 效果
 
9.11.1 好处
 
接受器-连接器模式提供以下好处:
 
增强面向对象软件的可复用性、可移植性和可扩展性:通过使服务初始化机制与后续服务处理去耦合来实现。例如,Acceptor和Connector中的应用无关的机制是可复用的组件,它们知道怎样(1)分别主动和被动地建立连接,以及(2)一旦连接被建立,初始化相关联的Service Handler。相反,Service Handler知道怎样执行应用特有的服务处理。
这样的事务分离是通过使初始化策略与服务处理策略去耦合来完成的。因而,每种策略都可以独立地发展。用于主动初始化的策略可以只编写一次,放进类库或构架中,并通过继承、对象合成或模板实例化来复用。因而,不需要为每个应用都重写同样的主动初始化代码。相反,服务可以根据不同的应用需求进行变化。通过使用Service Handler来参数化Acceptor和Connector,可以使这样的变化的影响被局限在软件的少量组件中。
 
改善应用健壮性:应用健壮性是通过彻底地使Service Handler和Acceptor去耦合来改善的。这样的去耦合确保了被动模式传输端点工厂peer_acceptor_不会偶然地被用于读写数据。这消除了在使用像socket或TLI[11]这样的弱类型网络编程接口时,可能发生的一类常见错误。
 
9.11.2 缺点
 
接受器-连接器模式有以下缺点:
 
额外的间接性:与直接使用底层的网络编程接口相比较,接受器-连接器模式可能带来额外的间接性。但是,支持参数化类型的语言(比如C++、Ada或Eiffel)可以较小的代价代价实现这些模式,因为编译器可以内联用于实现这些模式的方法调用。
 
额外的复杂性:对于简单客户应用(使用单个网络编程接口与单个服务器相连,并执行单项服务)来说,该模式可能会增加不必要的复杂性。
 
9.12 参见
 
接受器-连接器模式使用模板方法(Template Method)和工厂方法(Factory Method)模式[10]。Acceptor的accept和Connector的connect及complete函数是模板方法,它们在连接建立时为连接到远地对端并初始化Service Handler而实现通用的服务策略。模板方法的使用使子类可以对创建、连接和启用Concrete Service Handler的特定细节进行修改。工厂方法被用于使Service Handler的创建与它的后续使用去耦合。
接受器-连接器模式有与客户-分派器-服务器(Client-Dispatcher-Service)模式(在[21]中描述)类似的意图。它们都关心使主动连接建立与后续服务去耦合。主要的区别是接受器-连接器模式同时致力于同步和异步连接的被动和主动服务初始化,而客户-分派器-服务器)模式只专注于同步连接建立。
 
感谢
 
感谢Frank Buschmann和Hans Rohnert对本论文提出的有益意见。
 
参考文献
 
[1] W. R. Stevens, TCP/IP Illustrated, Volume 1. Reading, Massachusetts: Addison Wesley, 1993.
[2] G. Booch, Object Oriented Analysis and Design with Applications (2nd Edition). Redwood City, California: Benjamin/Cummings, 1993.
[3] D. C. Schmidt, “Reactor: An Object Behavioral Pattern for Concurrent Event Demultiplexing and Event Handler Dispatching,” in Pattern Languages of Program Design (J. O. Coplien and D. C. Schmidt, eds.), pp. 529–545, Reading, MA: Addison-Wesley, 1995.
[4] T. Harrison, I. Pyarali, D. C. Schmidt, and T. Jordan, “Proactor – An Object Behavioral Pattern for Dispatching Asynchronous Event Handlers,” in The 4th Pattern Languages of Programming Conference (Washington University technical report #WUCS-97-34), September 1997.
[5] R. G. Lavender and D. C. Schmidt, “Active Object: an Object Behavioral Pattern for Concurrent Programming,” in Pattern Languages of Program Design (J. O. Coplien, J. Vlissides, and N. Kerth, eds.), Reading, MA: Addison-Wesley, 1996.
[6] D. C. Schmidt, “ACE: an Object-Oriented Framework for Developing Distributed Applications,” in Proceedings of the 6th USENIX C++ Technical Conference, (Cambridge, Massachusetts), USENIX Association, April 1994.
[7] W. Pree, Design Patterns for Object-Oriented Software Development. Reading, MA: Addison-Wesley, 1994.
[8] W.R.Stevens,UNIX Network Programming, Second Edition. Englewood Cliffs, NJ: Prentice Hall, 1997.
[9] H. Custer, Inside Windows NT. Redmond, Washington: Microsoft Press, 1993.
[10] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995.
[11] D. C. Schmidt, T. H. Harrison, and E. Al-Shaer, “Object-Oriented Components for High-speed Network Programming,” in Proceedings of the 1st Conference on Object-Oriented Technologies and Systems,(Monterey,CA), USENIX, June 1, 995.
[12] D. C. Schmidt, “IPC SAP: An Object-Oriented Interface to Interprocess Communication Services,” C++ Report,vol.4, November/December 1992.
[13] W. R. Stevens, UNIX Network Programming, First Edition. Englewood Cliffs, NJ: Prentice Hall, 1990.
[14] S. Rago, UNIX System V Network Programming. Reading, MA: Addison-Wesley, 1993.
[15] D. L. Presotto and D. M. Ritchie, “Interprocess Communication in the Ninth Edition UNIX System,” UNIX Research System Papers, Tenth Edition, vol. 2, no. 8, pp. 523–530, 1990.
[16] Object Management Group, The Common Object Request Broker: Architecture and Specification, 2.0 ed., July 1995.
[17] D. C. Schmidt and C. Cleeland, “Applying Patterns to Develop Extensible ORB Middleware,” Submitted to the IEEE Communications Magazine, 1998.
[18] D. C. Schmidt, D. L. Levine, and S. Mungee, “The Design and Performance of Real-Time Object Request Brokers,” Computer Communications, vol. 21, pp. 294–324, Apr. 1998.
[19] D. C. Schmidt and T. Suda, “An Object-Oriented Framework for Dynamically Configuring Extensible Distributed Communication Systems,” IEE/BCS Distributed Systems Engineering Journal (Special Issue on Configurable Distributed Systems), vol. 2, pp. 280–293, December 1994.
[20] G. Blaine, M. Boyd, and S. Crider, “Project Spectrum: Scalable Bandwidth for the BJC Health System,” HIMSS, Health Care Communications, pp. 71–81, 1994.
[21] F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, and M. Stal, Pattern-Oriented Software Architecture - A System of Patterns. Wiley and Sons, 1996.
 
55/5<12345
 

评分:0

我来说两句

seccode

最新更新