您的位置:首页 > 其它

谷歌浏览器的源码分析(25)

2008-10-13 21:40 323 查看
上一次说到需要把显示的网络连接地址变成一个资源的消息发送出去,它是通过函数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))[/b] {

// 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);[/b]

#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[/b]的代码如下:

// 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,资源下载请求消息已经发送出去,那么这个消息又往何处而去呢?又怎么样通过网络连接下载回来呢?欲知后事如何,请继续看下一篇!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: