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 () // 處理請求並回復