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

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

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

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

如图9-7所示,如果Connect_Mode参数的值是SYNC,一旦连接同步地完成,SERVICE HANDLER将会被启用。该图与图9-4相类似,但是提供了另外的实现细节,比如get_handle和handle_event挂钩方法的使用。
 
 
图9-7 用于同步连接的Connector参与者之间的协作
 
为高效地与多个Peer相连,Connector可能还需要主动、异步地建立连接,也就是,不阻塞调用者。如图9-8所示,异步行为通过将ASYNC连接模式传递给Connector::connect来指定。该图与图9-5相类似,但是还提供了其他与当前实现相应的细节。
一旦实例化,PEER CONNECTOR类提供具体的IPC机制来同步或异步地发起连接。这里所显示的Connector模式的实现使用OS和通信协议栈所提供的异步连接机制。例如,在UNIX或Win32上,Connector可以将socket设置进非阻塞模式,并使用像select或WaitForMultipleObject这样的事件多路分离器来确定连接何时完成。
为处理还未完成的异步连接,Connector维护Service Handler映射表。因为Connector继承自Event Handler,当连接完成时,Initiation Dispatcher可以自动回调Connector的handle_event方法。
handle_event方法是一个适配器(Adapter)[10],它将Initiation Dispatcher的事件处理接口转换为对Connector模式的complete方法的调用。
 
 
图9-8 用于异步连接的Connector参与者之间的协作
 
Connector的handle_event方法如下所示:
 
template int
Connector::handle_event (HANDLE handle, EVENT_TYPE type)
{
// Adapt the Initiation_Dispatcher’s event
// handling API to the Connector’s API.
complete (handle);
}
 
complete方法启用刚刚成功完成非阻塞连接的SERVICE HANDLER,如下所示:
 
template int
Connector::complete (HANDLE handle)
{
SERVICE_HANDLER *service_handler = 0;
 
// Locate the SERVICE_HANDLER corresponding
// to the HANDLE.
handler_map_.find (handle, service_handler);
 
// Transfer I/O handle to SERVICE_HANDLER *.
service_handler->set_handle (handle);
 
// Remove handle from Initiation_Dispatcher.
Initiation_Dispatcher::instance
()->remove_handler (handle, WRITE_MASK);
 
// Remove handle from the map.
handler_map_.unbind (handle);
 
// Connection is complete, so activate handler.
activate_service_handler (service_handler);
}
 
complete方法在其内部映射表中查找并移除已连接的SERVICE HANDLER,并将I/O句柄传递给SERVICE HANDLER。最后,它通过调用activate_service_handler方法初始化SERVICE HANDLER。该方法委托由SERVICE HANDLER的open挂钩指定的并发策略。如下所示:
 
template int
Connector::activate_service_handler
(SERVICE_HANDLER *service_handler)
{
service_handler->open ();
}
 
Service Handler的open挂钩在连接成功建立时被调用。注意该挂钩都将被调用,不管(1)连接是同步还是异步发起的,或(2)它们是被主动还是被动连接的。这样的统一性使得开发者有可能编写这样的Service Handler,其处理可以完全地与它们是怎样被连接和初始化的去耦合。
 
接受器(Acceptor):该抽象类为被动连接建立和初始化Service Handler实现通用的策略。Acceptor的接口如下所示:
 
// The SERVICE_HANDLER is the type of service.
// The PEER_ACCEPTOR is the type of concrete
// IPC passive connection mechanism.
template
class PEER_ACCEPTOR>
class Acceptor : public Event_Handler
{
public:
// Initialize local_addr transport endpoint factory
// and register with Initiation_Dispatcher Singleton.
virtual int open(const PEER_ACCEPTOR::PEER_ADDR &local_addr);
 
// Factory Method that creates, connects, and
// activates SERVICE_HANDLER’s.
virtual int accept (void);
 
protected:
// Defines the handler’s creation strategy.
virtual SERVICE_HANDLER *make_service_handler (void);
 
// Defines the handler’s connection strategy.
virtual int accept_service_handler(SERVICE_HANDLER *);
 
// Defines the handler’s concurrency strategy.
virtual int activate_service_handler(SERVICE_HANDLER *);
 
// Demultiplexing hooks inherited from Event_Handler,
// which is used by Initiation_Dispatcher for
// callbacks.
virtual HANDLE get_handle (void) const;
virtual int handle_close (void);
 
// Invoked when connection requests arrive.
virtual int handle_event (HANDLE, EVENT_TYPE);
 
private:
// IPC mechanism that establishes
// connections passively.
PEER_ACCEPTOR peer_acceptor_;
};
 
// Useful "short-hand" macros used below.
#define SH SERVICE_HANDLER
#define PA PEER_ACCEPTOR
 
Acceptor通过特定类型的PEER ACCEPTOR和SERVICE HANDLER被参数化。PEER ACCEPTOR提供的传输机制被Acceptor用于被动地建立连接。SERVICE HANDLER提供的服务对与远地对端交换的数据进行处理。注意SERVICE HANDLER是由应用层提供的具体的服务处理器。
参数化类型使Acceptor的连接建立策略与服务处理器的类型、网络编程接口及传输层连接发起协议去耦合。就如同Connector一样,通过允许整体地替换Acceptor所用的机制,参数化类型的使用有助于提高可移植性。这使得连接建立代码可在含有不同网络编程接口(比如有socket,但没有TLI;反之亦然)的平台间移植。例如,取决于平台能够更为高效地支持socket还是TLI,PEER ACCEPTOR模板参数可以通过SOCK Acceptor或TLI Acceptor来实例化。
下面给出Acceptor的方法的实现。应用通过调用Acceptor的open方法来将其初始化。如下所示:
 
template int
Acceptor::open
(const PEER_ACCEPTOR::PEER_ADDR &local_addr)
{
// Forward initialization to the PEER_ACCEPTOR.
peer_acceptor_.open (local_addr);
 
// Register with Initiation_Dispatcher, which
// ‘‘double-dispatches’’ without get_handle()
// method to extract the HANDLE.
Initiation_Dispatcher::instance
()->register_handler (this, READ_MASK);
}
 
local_addr被传递给open方法。该参数含有网络地址,例如,本地主机的IP地址和TCP端口号,用于侦听连接。Open方法将此地址转发给PEER ACCEPTOR定义的被动连接接受机制。该机制初始化传输端点工厂,由后者将地址广告给有兴趣与此Acceptor连接的客户。
传输端点工厂的行为由用户所实例化的PEER ACCEPTOR的类型来决定。例如,它可以是socket[13]、TLI[14]、STREAM管道[15]、Win32命名管道等的C++包装。
在传输端点工厂被初始化后,open方法将其自身登记到Initiation Dispatcher。Initiation Dispatcher执行“双重分派”,回调Acceptor的get_handle方法,以获取底层传输端点工厂的HANDLE。如下所示:
 
template HANDLE
Acceptor::get_handle (void)
{
return peer_acceptor_.get_handle ();
}
 
Initiation Dispatcher在内部表中存储此HANDLE。Synchronous Event Demultipler(同步事件多路分离器),比如select,随即被用于检测和多路分离到来的来自客户的连接请求。因为Acceptor类继承自Event Handler,当连接从对端到达时,Initiation Dispatcher可以自动回调Acceptor的handle_event方法。该方法是一个适配器(Adapter),它将Initiation Dispatcher的事件处理接口转换为对Acceptor的accept方法的调用。如下所示:
 
template int
Acceptor::handle_event (HANDLE, EVENT_TYPE)
{
// Adapt the Initiation_Dispatcher’s event handling
// API to the Acceptor’s API.
accept ();
}
 
如下所示,accept方法是一个模板方法(Template Method)[10],它为创建新SERVICE HANDLER、将连接接受进其中并启用服务而实现接受器-连接器模式的被动初始化策略:
 
template int
Acceptor::accept (void)
{
// Create a new SERVICE_HANDLER.
SH *service_handler = make_service_handler ();
 
// Accept connection from client.
accept_service_handler (service_handler);
 
// Activate SERVICE_HANDLER by calling
// its open() hook.
activate_service_handler (service_handler);
}
 
该方法非常简洁,因为它将所有低级细节都分解进具体的SERVICE HANDLER和PEER ACCEPTOR中,后二者通过参数化类型被实例化,并可被Acceptor的子类定制。特别地,因为accept是模板方法,子类可以扩展Acceptor的任意或所有的连接建立和初始化策略。这样的灵活性使得开发者有可能编写这样的Service Handler,其行为与它们被被动地连接和初始化的方式是相分离的。
make_service_handler工厂方法定义Acceptor用于创建SERVICE HANDLER的缺省策略。如下所示:
 
template SH *
Acceptor::make_service_handler (void)
{
return new SH;
}
 
缺省行为使用了“请求策略”(demand strategy),它为每个新连接创建新的SERVICE HANDLER。但是,Acceptor的子类可以重定义这一策略,以使用其他策略创建SERVICE HANDLE,比如创建单独的单体(Singleton)[10]或从共享库中动态链接SERVICE HANDLER。
accept_service_handler方法在下面定义Acceptor所用的SERVICE HANDLER连接接受策略:
 
template int
Acceptor::accept_service_handler(SH *handler)
{
peer_acceptor_->accept (handler->peer ());
}
 
缺省行为委托PEER ACCEPTOR所提供的accept方法。子类可以重定义accept_service_handler方法,以执行更为复杂的行为,比如验证客户的身份,以决定是接受还是拒绝连接。
Activate_service_handler定义Acceptor的SERVICE HANDLER并发策略:
 
template int
Acceptor::activate_service_handler(SH *handler)
{
handler->open ();
}
 
该方法的缺省行为是通过调用SERVICE HANDLER的open挂钩将其启用。这允许SERVICE HANDLER选择它自己的并发策略。例如,如果SERVICE HANDLER继承自Event Handler,它可以登记到Initiation Dispatcher,从而在事件发生在SERVICE HANDLER的PEER STREAM通信端点上时,使Initiation Dispatcher能够分派其handle_event方法。Concrete Acceptor可以重定义此策略,以完成更为复杂的并发启用。例如,子类可以使SERVICE HANDLER成为主动对象(Active Object)[5],使用多线程或多进程来处理数据。
当Acceptor终止时,无论是由于错误还是由于整个应用的关闭,Initiation Dispatcher都调用Acceptor的handle_close方法,后者可以释放任何动态获取的资源。在此例中,handle_close方法简单地将close请求转发给PEER ACCEPTOR的传输端点工厂。如下所示:
 
template int
Acceptor::handle_close (void)
{
peer_acceptor_.close ();
}
 

53/5<12345>
 

评分:0

我来说两句

seccode