上一次介绍到把网页连接地址生成一个消息通过IPC机制把消息发送出去,那么IPC的通讯机制是怎么样的呢?又是发送给谁呢?
由于这个浏览器是使用多进程的架构来工作的,所以进程之间就需要相互交流,这种交流是就是通讯,可以从源码里看到它是使用IPC的机制来通讯,实际采用的技术,就是Windows的命名管道的方式。可以看到这段代码:
#001 bool Channel::CreatePipe(const wstring& channel_id, Mode mode) {
#002 DCHECK(pipe_ == INVALID_HANDLE_VALUE);
#003 const wstring pipe_name = PipeName(channel_id);
#004 if (mode == MODE_SERVER) {
#005 SECURITY_ATTRIBUTES security_attributes = {0};
#006 security_attributes.bInheritHandle = FALSE;
#007 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
#008 if (!win_util::GetLogonSessionOnlyDACL(
#009 reinterpret_cast<SECURITY_DESCRIPTOR**>(
#010 &security_attributes.lpSecurityDescriptor))) {
#011 NOTREACHED();
#012 }
#013
#014 pipe_ = CreateNamedPipeW(pipe_name.c_str(),
#015 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
#016 FILE_FLAG_FIRST_PIPE_INSTANCE,
#017 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
#018 1, // number of pipe instances
#019 BUF_SIZE, // output buffer size (XXX tune)
#020 BUF_SIZE, // input buffer size (XXX tune)
#021 5000, // timeout in milliseconds (XXX tune)
#022 &security_attributes);
#023 LocalFree(security_attributes.lpSecurityDescriptor);
#024 } else {
#025 pipe_ = CreateFileW(pipe_name.c_str(),
#026 GENERIC_READ | GENERIC_WRITE,
#027 0,
#028 NULL,
#029 OPEN_EXISTING,
#030 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
#031 FILE_FLAG_OVERLAPPED,
#032 NULL);
#033 }
上面这段代码通过WINDOWS API函数CreateNamedPipeW函数来创建命名管道的服务器端,而通过WINDOWS API函数CreateFileW来打开客户端,这样两个进程之间就建立起来通讯的管道,两个进程之间的消息就可以相互发送了。
在浏览网页连接的消息,就是通过IPC的机制,让类RenderProcessHost把消息发送出去,那么这个消息是谁在另一端接收的呢?按照IPC的机制可知是另外一个进程在接收,这个进程就是类RenderProcess。
类RenderProcessHost把所有的消息通过类IPC::ChannelProxy发送出去,在另一个子进程里通过类RenderThread和类RenderView来接收消息,然后在类RenderThread和类RenderView把消息分发处理。