上一次說到需要把顯示的網絡連接地址變成一個資源的消息發送出去,它是通過函數
ResourceHandle::create
來實現的,但這個函數到底是怎么樣實現的呢?現在就分析它的實現代碼,了解它怎么樣把資源變換成消息,并且通過
IPC
機制把消息發送到資源下載進程去。數
ResourceHandle::create
的代碼如下:
#001
?
PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request,
#002
???????????????????????????????????????????????????
ResourceHandleClient* client,
#003
???????????????????????????????????????????????????
Frame* deprecated,
#004
?????????????????????????????????????
??????????????
bool defersLoading,
#005
???????????????????????????????????????????????????
bool shouldContentSniff,
#006
???????????????????????????????????????????????????
bool mightDownloadFromHandle) {
上面的參數
request
是把所有請求網絡連接地址信息傳進來了。
#007
???
RefPtr<ResourceHandle> newHandle(
#008
???????
new ResourceHandle(request, client, defersLoading, shouldContentSniff,
#009
??????????????????????????
mightDownloadFromHandle));
這里創建資源類
ResourceHandle
對象,通過它來生成一個消息發送出去。
#010
?
#011
???
if (newHandle->start(NULL))
#012
????
?
return newHandle.release();
上面的代碼里,調用函數
start
來處理資源請求下載。
#013
?
#014
???
return NULL;
#015
?
}
在這個函數里調用
newHandle->start
函數來處理,其實它是調用下面的函數來工作的:
bool ResourceHandle::start(Frame* deprecated) {
?
return d->Start(NULL);
}
那么這里的
d
實例是什么呢?可以通過
ResourceHandle
的構造函數來看到它的類,如下:
ResourceHandle::ResourceHandle(const ResourceRequest& request,
??????????????????????????????
ResourceHandleClient* client,
??????????????????????????????
bool defersLoading,
??????????????????????????????
bool shouldContentSniff,
?????????????????
?????????????
bool mightDownloadFromHandle)
#pragma warning(suppress: 4355)
?
// it's okay to pass |this| here!
?????
:
d(new ResourceHandleInternal(this, request, client))
{
?
// TODO(darin): figure out what to do with the two bool params
}
???????????????
可以看到
d
是類
ResourceHandleInternal
的實例,這就是說調用
d->Start
函數,其實就是調用下面的函數:
#001
?
bool ResourceHandleInternal::Start(
#002
?????
ResourceLoaderBridge::SyncLoadResponse* sync_load_response) {
#003
???
DCHECK(!bridge_.get());
#004
?
#005
???
// The WebFrame is the Frame's FrameWinClient
#006
???
WebFrameImpl* webframe =
#007
???????
request_.frame() ? WebFrameImpl::FromFrame(request_.frame()) : NULL;
......
#154
?
#155
???
if (sync_load_response) {
#156
?????
bridge_->SyncLoad(sync_load_response);
#157
?????
return true;
#158
???
}
#159
?
通過上面的處理,然后就調用橋連接成員
bridge_
來創建消息。
#160
???
bool rv = bridge_->Start(this);
#161
???
if (rv) {
#162
?????
pending_ = true;
#163
?????
job_->ref();
?
// to be released when we get a OnCompletedRequest.
#164
???
} else {
#165
?????
bridge_.reset();
#166
???
}
#167
?
#168
???
return rv;
#169
?
}
在這里使用一個設計模式,叫橋連接模式。函數
bridge_->Start
的代碼如下:
// Writes a footer on the message and sends it
bool IPCResourceLoaderBridge::Start(Peer* peer) {
?
if (request_id_ != -1) {
???
NOTREACHED() << "Starting a request twice";
???
return false;
?
}
?
RESOURCE_LOG("Starting request for " << url_);
保存當前接收的連接端點。
?
peer_ = peer;
生成請求
ID
,以便返回數據時可以找到相應的顯示進程和窗口。
?
// generate the request ID, and append it to the message
?
request_id_ = dispatcher_->AddPendingRequest(peer_, request_.resource_type,
??????????????????????????????????????????????
request_.mixed_content);
找到
IPC
的消息發送對象,然后創建
ViewHostMsg_RequestResource
消息并發送出去。
?
IPC::Message::Sender* sender = dispatcher_->message_sender();
?
bool ret = false;
?
if (sender)
???
ret = sender->Send(new ViewHostMsg_RequestResource(MSG_ROUTING_NONE,
??????????????????????????????????????????????????????
request_id_,
??????????????????????????????????????????????????????
request_));
?
return ret;
}
通過上面漫長的分析,總算搞清楚了這個過程:
從界面開始輸入
URL
地址,然后界面把
URL
發送到渲染進程,渲染進程再進行處理,把這個
URL
連接請求再次發送到資源下載進程去處理。串起來是一個極其簡單的過程,但在這個瀏覽器里比較復雜的,因為它是多進程的瀏覽器,進程之間相互消息傳送,就比其它瀏覽器復雜,并且它還有很多安全策略的使用和優化處理,導致這個處理過程是比較復雜的。
OK
,資源下載請求消息已經發送出去,那么這個消息又往何處而去呢?又怎么樣通過網絡連接下載回來呢?欲知后事如何,請繼續看下一篇!
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
