转载于:http://www.cnblogs.com/TianFang/archive/2006/12/22/600191.htmlhtml
接受器-链接器设计模式(Acceptor-Connector)使分布式系统中的链接创建及服务初始化与一旦服务初始化后所执行的处理去耦合。编程
这样的去耦合经过三种组件来完成:acceptor、connector 和 servicehandler(服务处理器)。设计模式
结构服务器
1. 服务处理器(Service Handler):
Service Handler 实现应用服务,一般扮演客户角色、服务器角色,或同时扮演这两种角色。它提供挂钩方法,由 Acceptor 或 Connector 调用,以在链接创建时启用应用服务。此外,Service Handler 还提供数据模式传输端点,其中封装了一个 I/O 句柄。一旦链接和初始化后,该端点被 Service Handler 用于与和其相连的对端交换数据。网络
2. 接受器(Acceptor):
Acceptor 是一个工厂,实现用于被动地创建链接并初始化与其相关联的 Service Handler 的策略。此外,Acceptor 包含有被动模式的传输端点工厂,它建立新的数据模式端点,由 Service Handler 用于在相连的对端间传输数据。经过将传输端点工厂绑定到网络地址,好比 Acceptor 在其上侦听的 TCP 端口号,Acceptor的 open 方法对该工厂进行初始化。
一旦初始化后,被动模式的传输端点工厂侦听来自对端的链接请求。当链接请求到达时,Acceptor 建立 Service Handler,并使用它的传输端点工厂来将新链接接受进Service Handler 中。并发
3. 链接器(Connector):
Connector 是一个工厂,实现用于主动地创建链接并初始化与其相关联的 Service Handler 的策略。它提供方法,由其发起到远地 Acceptor 的链接。一样地,它还提供另外一个方法,完成对 Service Handler 的启用;该处理器的链接是被同步或异步地发起的。Connector 使用两个分开的方法来透 明地支持异步链接创建。异步
4. 分派器(Dispatcher):
为 Acceptor,Dispatcher 将在一或多个传输端点上接收到的链接请求多路分离给适当的 Acceptor。Dispatcher容许多个 Acceptor 向其登记,以侦听同时在不一样端口上从不一样对端而来的链接。 为 Connector,Dispatcher 处理异步发起的链接的完成。在这种状况下,当异步链接被创建时,Dispatcher 回调 Connector。Dispatcher 容许多个 Service Handler 经过一个 Connector 来异步地发起和完成它们 的链接。注意对于同步链接创建,Dispatcher 并非必需的,由于发起链接的线程控制也完成服务服务处 理器的启用。
Dispatcher 一般使用事件多路分离模式来实现,这些模式由反应器(Reactor)或前摄器(Proactor) 来提供,它们分别处理同步和异步的多路分离。一样地,Dispatcher 也可使用主动对象(Active Obj ect)模式[5]来实现为单独的线程或进程。socket
协做分布式
Acceptor 组件协做函数
Acceptor 和 Service Handler 之间的协做。这些协做被划分为三个阶段:
1. 端点初始化阶段:
为被动地初始化链接,应用调用 Acceptor 的 open 方法。该方法建立被动模式的传 输端点,将其绑定到网络地址,例如,本地主机的 IP 地址和 TCP 端口号,并随后侦听来自对端 Connector 的链接请求。其次,open 方法将 Acceptor 对象登记到 Dispatcher,以使分派器可以在链接事件 到达时回调 Acceptor。最后,应用发起 Dispatcher 的事件循环,等待链接请求从对端 Connector 到来。
2. 服务初始化阶段:
当链接请求到达时,Dispatcher 回调 Acceptor 的accept 方法。该方法装配如下活动 所必需的资源:
3. 服务处理阶段:
在链接被动地创建和 Service Handler 被初始化后,服务处理阶段开始了。在此阶段, 应用级通讯协议,好比 HTTP 或 IIOP,被用于在本地 Service Handler 和与其相连的远地 Peer 之间、 经由前者的 peer_stream_端点交换数据。当交换完成,可关闭链接和 Service Handler,并释放资源。
Connector 组件协做
Connector 组件可使用同步和异步两种方式来初始化它的 Service Handle,这里仅介绍一下同步时的协做状况。
同步的 Connector 状况中的参与者之间的协做可被划分为如下三个阶段:
实现
运行通常步骤:
主要角色:Service Handler(服务处理器)、Acceptor 和 Connector。
服务处理器:该抽象类继承自 Event_Handler,并为客户、服务器或同时扮演两种角色的组件所提供 的服务处理提供通用接口。应用必须经过继承来定制此类,以执行特定类型的服务。Service Handler 接口以下所示:
1 template <class PEER_STREAM> 2 class Service_Handler : public Event_Handler 3 { 4 public: 5 //链接成功后的初始化入口函数 (子类定义). 6 virtual int open (void) = 0; 7 //返回通讯流的引用 8 PEER_STREAM &peer (void) 9 { 10 return peer_stream_; 11 } 12 };
一旦 Acceptor 或 Connector 创建了链接,它们调用 Service Handler 的 open 挂钩。该纯虚方法必须被 Concrete Service Handler 子类定义;后者执行服务特有的初始化和后续处理。
链接器:该抽象类实现主动链接创建和初始化 Service Handler 的通用策略。它的接口以下所示:
1 template <class SERVICE_HANDLER,class PEER_CONNECTOR> 2 class Connector : public Event_Handler 3 { 4 public: 5 enum Connect_Mode 6 { 7 SYNC, //以同步方式链接 8 ASYNC //以异步方式链接 9 }; 10 // 主动链接并激活服务处理器 11 int connect (SERVICE_HANDLER *sh, 12 const PEER_CONNECTOR::PEER_ADDR &addr, 13 Connect_Mode mode); 14 protected: 15 //定义链接激活策略 16 virtual int connect_service_handler(SERVICE_HANDLER *sh, 17 const PEER_CONNECTOR::PEER_ADDR &addr, 18 Connect_Mode mode); 19 // Defines the handler's concurrency strategy. 20 virtual int activate_service_handler(SERVICE_HANDLER *sh); 21 // 当以异步方式链接完成时激活服务处理器 22 virtual int complete (HANDLE handle); 23 private: 24 // IPC mechanism that establishes 25 // connections actively. 26 PEER_CONNECTOR connector_; 27 };
Conncetor 经过特定类型的 PEER CONNECTOR 和 SERVICE HANDLER 被参数化。PEER CONNECTO R 提供的传输机制被 Connector 用于主动地创建链接,或是同步地、或是异步地。SERVICE HANDLER提供的服务对与相连的对端交换的数据进行处理。C++参数化类型被用于使(1)链接创建策略与(2)服务处理器类型、网络编程接口和传输层链接协议去耦合。
参数化类型是有助于提升可移植性的实现决策。例如,它们容许总体地替换 Connector 所用的 IPC 机 制。这使得 Connector 的链接创建代码可在含有不一样网络编程接口(例如,有 socket,但没有 TLI;反之 亦然)的平台间进行移植。
Service Handler 的 open 挂钩在链接成功创建时被调用。
接受器(Acceptor):该抽象类为被动链接创建和初始化 Service Handler 实现通用的策略。Acceptor 的接 口以下所示:
1 template <class SERVICE_HANDLER, 2 class PEER_ACCEPTOR> 3 class Acceptor : public Event_Handler 4 { 5 public: 6 // Initialize local_addr transport endpoint factory 7 // and register with Initiation_Dispatcher Singleton. 8 virtual int open(const PEER_ACCEPTOR::PEER_ADDR &local_addr); 9 // Factory Method that creates, connects, and 10 // activates SERVICE_HANDLER's. 11 virtual int accept (void); 12 protected: 13 //定义服务处理器的建立策略 14 virtual SERVICE_HANDLER *make_service_handler (void); 15 // 定义服务处理器的链接策略 16 virtual int accept_service_handler(SERVICE_HANDLER *); 17 //定义服务处理器的激活策略 18 virtual int activate_service_handler(SERVICE_HANDLER *); 19 // Demultiplexing hooks inherited from Event_Handler, 20 // which is used by Initiation_Dispatcher for 21 // callbacks. 22 virtual HANDLE get_handle (void) const; 23 virtual int handle_close (void); 24 private: 25 // IPC mechanism that establishes 26 // connections passively. 27 PEER_ACCEPTOR peer_acceptor_; 28 };
Acceptor 经过特定类型的 PEER ACCEPTOR 和 SERVICE HANDLER 被参数化。PEER ACCEPTOR 提供的传输机制被 Acceptor 用于被动地创建链接。SERVICE HANDLER 提供的服务对与远地对端交换的 数据进行处理。注意 SERVICE HANDLER 是由应用层提供的具体的服务处理器。
参数化类型使 Acceptor 的链接创建策略与服务处理器的类型、网络编程接口及传输层链接发起协议去耦合。就如同 Connector 同样,经过容许总体地替换 Acceptor 所用的机制,参数化类型的使用有助于提升可移植性。这使得链接创建代码可在含有不一样网络编程接口(好比有 socket,但没有 TLI;反之亦然)的平台间移植。
make_service_handler 工厂方法定义 Acceptor 用于建立 SERVICE HANDLER 的缺省策略。以下所示:
1 template <class SH, class PA> SH * 2 Acceptor<SH, PA>::make_service_handler (void) 3 { 4 return new SH; 5 }
缺省行为使用了"请求策略"(demand strategy),它为每一个新链接建立新的 SERVICE HANDLER。可是, Acceptor 的子类能够重定义这一策略,以使用其余策略建立 SERVICE HANDLE,好比建立单独的单体 (Singleton)[10]或从共享库中动态连接 SERVICE HANDLER。
accept_service_handler 方法在下面定义 Acceptor 所用的 SERVICE HANDLER 链接接受策略:
1 template <class SH, class PA> int 2 Acceptor<SH, PA>::accept_service_handler(SH *handler) 3 { 4 peer_acceptor_->accept (handler->peer ()); 5 }
缺省行为委托 PEER ACCEPTOR 所提供的 accept 方法。子类能够重定义 accept_service_handler 方法,以 执行更为复杂的行为,好比验证客户的身份,以决定是接受仍是拒绝链接。
Activate_service_handler 定义 Acceptor 的 SERVICE HANDLER 并发策略:
程序示例:
在ACE中,默认的服务处理器是ACE_Svc_Handler,这也是一个模版类,能够经过相关的参数特化。因为ACE_Svc_Handler继承自ACE_Task和ACE_Event_Handler,功能至关强大,同时也存在必定开销,若是须要减少开销能够本身写一个仅继承自ACE_Event_Handler的服务处理器。
为了演示简单,我这里就以一个EchoServer的服务器端和客户端为例,其中接收器和链接器都采用缺省策略,并无进行重载。
服务器端:
1 #include "ace/Reactor.h" 2 #include "ace/Svc_Handler.h" 3 #include "ace/Acceptor.h" 4 #include "ace/Synch.h" 5 #include "ace/SOCK_Acceptor.h" 6 7 class My_Svc_Handler; 8 typedef ACE_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> MyAcceptor; 9 10 class My_Svc_Handler: 11 public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH> 12 { 13 public: 14 int open(void*) 15 { 16 ACE_OS::printf("\nConnection established\n"); 17 18 //注册相应事件 19 ACE_Reactor::instance()->register_handler(this, 20 ACE_Event_Handler::READ_MASK); 21 return 0; 22 } 23 24 int handle_input(ACE_HANDLE) 25 { 26 int rev = peer().recv(data,1024); 27 if(rev == 0) 28 { 29 delete this; 30 } 31 else 32 { 33 data[rev]='\0'; 34 ACE_OS::printf("<<rev:\t %s\n",data); 35 peer().send(data,rev+1); 36 return 0; 37 } 38 } 39 private: 40 char data[1024]; 41 }; 42 int main(int argc, char* argv[]) 43 { 44 ACE_INET_Addr addr(3000); 45 MyAcceptor acceptor(addr,ACE_Reactor::instance()); 46 47 while(1) 48 ACE_Reactor::instance()->handle_events(); 49 } 50 51 客户端: 52 53 #include "ace/Reactor.h" 54 #include "ace/Svc_Handler.h" 55 #include "ace/Connector.h" 56 #include "ace/Synch.h" 57 #include "ace/SOCK_Connector.h" 58 59 class My_Svc_Handler; 60 typedef ACE_Connector<My_Svc_Handler,ACE_SOCK_CONNECTOR> MyConnector; 61 62 class My_Svc_Handler: 63 public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH> 64 { 65 public: 66 int open(void*) 67 { 68 ACE_OS::printf("\nConnection established\n"); 69 70 //注册相应事件 71 ACE_Reactor::instance()->register_handler(this, 72 ACE_Event_Handler::READ_MASK); 73 return 0; 74 } 75 76 int handle_input(ACE_HANDLE) 77 { 78 int rev = peer().recv(data,1024); 79 if(rev == 0) 80 { 81 delete this; 82 } 83 else 84 { 85 data[rev]='\0'; 86 ACE_OS::printf("<<rev:\t %s\n",data); 87 return 0; 88 } 89 } 90 91 int sendData(char *msg) 92 { 93 ACE_OS::printf("<<send:\t %s\n",msg); 94 return peer().send(msg,strlen(msg)); 95 } 96 97 private: 98 char data[1024]; 99 }; 100 int main(int argc, char* argv[]) 101 { 102 ACE_INET_Addr addr(3000,"192.168.1.142"); 103 104 My_Svc_Handler *svchandler = new My_Svc_Handler(); 105 MyConnector connector; 106 107 if(connector.connect(svchandler,addr)==-1) 108 { 109 ACE_OS::printf("Connect fail"); 110 } 111 112 svchandler->sendData("hello wrold"); 113 114 while(1) 115 ACE_Reactor::instance()->handle_events(); 116 }