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

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

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

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

9.8.3 应用层
 
应用层提供具体的进程间通信(IPC)机制和具体的Service Handler。IPC机制被封装在C++类中,以简化编程、增强复用,并使开发者能够整个地替换IPC机制。例如,9.9中使用的SOCK Acceptor、SOCK Connector,以及SOCK Stream类是ACE C++ socket包装类库[11]的一部分。它们通过高效、可移植和类型安全的C++包装来封装像TCP和SPX这样的面向连接协议的面向流的语义。
应用层中的三个主要角色描述如下:
 
具体的服务处理器(Concrete Service Handler):该类定义具体的应用服务,由Concrete Acceptor或Concrete Connector启用。Concrete Service Handler通过特定类型的C++ IPC包装(它与和其相连的对端进行数据交换)来实例化。
 
具体的连接器(Concrete Connector):该类通过具体的参数化类型参数SERVICE HANDLER和PEER CONNECTOR来实例化通用的Connector工厂。
 
具体的接受器(Concrete Acceptor):该类通过具体的参数化类型参数SERVICE HANDLER和PEER ACCEPTOR来实例化通用的Acceptor工厂。
 
Concrete Service Handler还可以定义服务的并发策略。例如,Service Handler可以从Event Handler继承,并采用反应堆(Reactor)[3]模式来在单线程控制中处理来自对端的数据。相反,Service Handler也可以使用主动对象(Active Object)模式[5]处理到来的数据,而其所在线程控制与Acceptor连接它所用的不相同。下面,我们为我们的Gateway例子实现Concrete Service Handler,演示怎样灵活地配置若干不同的并发策略,而又不影响接受器-连接器模式的结构或行为。
在9.9的示例代码中,SOCK Connector和SOCK Acceptor是分别用于主动和被动地建立连接的IPC机制。同样地,SOCK Stream被用作数据传输递送机制。但是,通过其他机制(比如TLI Connector或Named Pipe Acceptor)来参数化Connector和Acceptor也是相当直接的,因为IPC机制被封装在C++包装类中。同样地,通过使用不同的PEER STREAM,(比如SVR4 UNIX TLI Stream或Win32 Named Pipe Stream)来参数化Concrete Service Handler,很容易改变数据传输机制。
9.9演示怎样实例化Concrete Service Handler、Concrete Connector和Concrete Acceptor,实现9.2中描述的Peer和Gateway。这个特定的应用层例子定制连接层中的Connector和Acceptor组件所提供的通用初始化策略。
 
9.9 例子解答
 
下面的代码演示9.2中描述的Peer和Gateway怎样使用接受器-连接器模式来简化连接建立和服务初始化。9.9.1演示Peer怎样扮演被动角色,9.9.2演示Gateway怎样在与被动的Peer的连接建立中扮演主动角色。
 
9.9.1 用于对端的具体组件
 
图9-9演示Concrete Acceptor和Concrete Service Handler组件是怎样在Peer中构造的。该图中的Acceptor组件与图9-11中的Connector组件是互补的。
 
用于与Gateway通信的服务处理器:如下所示的Status Handler、Bulk Data Handler和Command Handler类处理发送到Gateway和从Gateway接收的路由消息。因为这些Concrete Service Handler类继承自Service Handler,它们可以被Acceptor被动地初始化。
为演示接受器-连接器模式的灵活性,这些Service Handler中的每个open例程都可以实现不同的并发策略。特别地,当Status Handler被启用时,它运行在单独的线程中;Bulk Data Handler作为单独的进程运行;而Command Handler运行在与Initiation Dispatcher相同的线程中,后者为Acceptor工厂进行连接请求的多路分离。注意这些并发策略的改变并不影响Acceptor的实现,它是通用的,因而也是高度灵活和可复用的。
我们从定义一个Service Handler开始,它为基于socket的数据传输使用SOCK Stream:
 
typedef Service_Handler PEER_HANDLER;
 
图9-9 对端的Acceptor参与者的结构
 
PEER HANDLER的typedef构成所有后续服务处理器的基础。例如,Status Handler类处理发送到Gateway和从Gateway接收的状态数据:
 
class Status_Handler : public PEER_HANDLER
{
public:
// Performs handler activation.
virtual int open (void)
{
// Make handler run in separate thread (note
// that Thread::spawn requires a pointer to
// a static method as the thread entry point).
Thread::spawn (&Status_Handler::service_run, this);
}
 
// Static entry point into thread, which blocks
// on the handle_event () call in its own thread.
static void *service_run (Status_Handler *this_)
{
// This method can block since it
// runs in its own thread.
while (this_->handle_event () != -1)
continue;
}
 
// Receive and process status data from Gateway.
virtual int handle_event (void)
{
char buf[MAX_STATUS_DATA];
stream_.recv (buf, sizeof buf);
// ...
}
 
// ...
};
 
PEER HANDLER还可被子类化,以生成具体的服务处理器,处理大块数据和命令。例如,Bulk Data Handler类处理发送到Gateway和从Gateway接收的大块数据:
 
class Bulk_Data_Handler : public PEER_HANDLER
{
public:
// Performs handler activation.
virtual int open (void)
{
// Handler runs in separate process.
if (fork () == 0) // In child process.
 
// This method can block since it
// runs in its own process.
while (handle_event () != -1)
continue;
 
// ...
}
 
// Receive and process bulk data from Gateway.
virtual int handle_event (void)
{
char buf[MAX_BULK_DATA];
stream_.recv (buf, sizeof buf);
// ...
}
 
// ...
};
 
Command Handler类处理发送到Gateway和从Gateway接收的命令。
 
class Command_Handler : public PEER_HANDLER
{
public:
// Performs handler activation.
virtual int open (void)
{
// Handler runs in same thread as main
// Initiation_Dispatcher singleton.
Initiation_Dispatcher::instance
()->register_handler (this, READ_MASK);
}
 
// Receive and process command data from Gateway.
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.
stream_.recv (buf, sizeof buf);
 
// ...
}
 
//...
};
 
用于创建Peer Service Handler的接受器:如下所示的s_acceptor、bd_acceptor和c_acceptor对象是Concrete Acceptor工厂实例,它们分别创建并启用Status Handler、Bulk Data Handler和Command Handler。
 
// Accept connection requests from Gateway and
// activate Status_Handler.
Acceptor s_acceptor;
 
// Accept connection requests from Gateway and
// activate Bulk_Data_Handler.
Acceptor bd_acceptor;
 
// Accept connection requests from Gateway and
// activate Command_Handler.
Acceptor c_acceptor;
 
注意模板和动态绑定的使用是怎样允许特定细节灵活地变化的。特别地,在整个这一部分中,当并发策略被修改时,没有Acceptor组件发生变化。这样的灵活性的原因是并发策略已被分解进Service Handler中,而不是与Acceptor耦合在一起。
 
 
图9-10 对端中的Acceptor组件的对象图
 
Peer主函数:主程序通过调用具体的Acceptor工厂的open挂钩(以每个服务的TCP端口为参数)来对它们进行初始化。如9.8.2所示,每个Acceptor工厂自动地在它的open方法中将其自身登记到Initiation Dispatcher的实例。
 
// Main program for the Peer.
int main (void)
{
// Initialize acceptors with their
// well-known ports.
s_acceptor.open (INET_Addr (STATUS_PORT));
bd_acceptor.open (INET_Addr (BULK_DATA_PORT));
c_acceptor.open (INET_Addr (COMMAND_PORT));
 
// Event loop that handles connection request
// events and processes data from the Gateway.
for (;;)
Initiation_Dispatcher::instance()->handle_events ();
}
 
一旦Acceptor被初始化,主程序进入事件循环,使用Initiation Dispatcher来检测来自Gateway的连接请求。当连接到达时,Initiation Dispatcher回调适当的Acceptor,由其创建适当的PEER HANDLER来执行服务、将连接接受进处理器、并启用处理器。
图9-10演示在与Gateway(如图9-12所示)的四个连接被建立、以及四个Service Handler被创建和启用后,Peer中的Concrete Acceptor组件之间的关系。在Concrete Service Handler与Gateway交换数据的同时,三个Acceptor也在主线程中持续地侦听新连接。

54/5<12345>
 

评分:0

我来说两句

seccode