JAWS服务程序启动流程
1.利用ACE_Service_Config加载配置文件,并利用ACE反射机制构造HTTP_Server对象并初始化init() (ACE反射机制,开专题解析)
2.根据配置文件中的创建HTTP_Handler_Factory,ACE_Handler工厂类
if (this->strategy_ != (JAWS::JAWS_POOL | JAWS::JAWS_ASYNCH))
{
if (this->caching_)
{
ACE_NEW_RETURN(f, Synch_HTTP_Handler_Factory(), -1); //默认配置
}
else
{
ACE_NEW_RETURN(f, No_Cache_Synch_HTTP_Handler_Factory(), -1);
}
}
ACE_Auto_Ptr<HTTP_Handler_Factory> factory (f); //内存托管
3.根据配置文件的同步策略,构造线程模型对象
创建线程池
switch (this->strategy_)
{
case (JAWS::JAWS_POOL | JAWS::JAWS_ASYNCH):
return this->asynch_thread_pool();
case (JAWS::JAWS_PER_REQUEST | JAWS::JAWS_SYNCH):
return this->thread_per_request(*factory.get());
case (JAWS::JAWS_POOL | JAWS::JAWS_SYNCH):
default:
return this->synch_thread_pool(*factory.get()); //默认配置,同步线程池
}
启动acceptor和线程池
HTTP_Server::synch_thread_pool
acceptor_.open() //启动ACE_Acceptor对象
Synch_Thread_Pool_Task //创建同步线程池对象
tm_.wait (); //等待线程池退出
4.线程任务回调
Synch_Thread_Pool_Task::svc
for(::)
ACE_SOCK_Stream stream; // Stream对象
acceptor_.accept(stream) //接受连接请求,阻塞,有连接请求时才会返回
ACE_Message_Block *mb=new ACE_Message_Block(); //接收缓冲区
HTTP_Handler *handler = factory_.create_http_handler(); //ACE_Handler工厂类生产
handler->open (stream.get_handle (), *mb); //处理HTTP_Handler
mb->release () //释放接收缓冲区
5.HTTP_Handler Http事件句柄
HTTP_Handler派生于JAWS_Synch_IOr在用户回调中被构造、处理、销毁,生周期完全由应用层控制,所以没有派生于ACE_Handlor。HTTP_Handler Http事件句柄
核心函数:
read_complete (ACE_Message_Block &) //同步接收,请求处理都在里面
JAWS<1代>线程模型分析
作为网络服务器框架,JAW 1代框架采用多线程-同步IO模型,一个线程处理一个http请求+回复。
优点是,开发简单,代码条理清晰。
缺点是,所有IO操作需要程序在应用层显式调用,比如http的请求解析时,一次收不完数据,所以需要根据http协议的规定,比如是否根据content-length判断是否接收完数据,未接收完整,则还需要继续调用recv接口。这使得应用层代码和网络层相互耦合。
http请求处理伪代码:
HTTP_Handler::read_complete(ACE_Message_Block &message_block) //传入消息缓冲区
| switch (this->request_.parse_request (message_block))
| | case 0: //说明http请求没收完
| | | do
计算剩余长度,缓冲区最大长度HTTP_Handler::MAX_REQUEST_SIZE
io_.read (message_block, 剩余长度)
while (0);
| | default: //接收完整http
| | | response_.process_request () // 处理请求并回复