CEF概述
Chromium Embedded Framework (CEF) 是一个基于Google Chromium 的开源项目。与Google Chromium 不同,CEF致力于Google Chrome项目的发展,CEF可以很方便的将浏览器嵌入到第三方应用。CEF将开发者从底层的Chromium和Blink的复杂代码释放出来,提供了一套稳定的API。CEF大部分特性都已经实现,使得开发者进行少量的定制即可实现其功能。CEF在世界上已经有超过100万安装量,许多公司和机构将CEF嵌入到他们的产品中。
目录结构
CEF二进制源码可以在(http://www.magpcss.net/cef_downloads/)下载。包含了在指定平台指定版本所需要的全部文件。无论在哪个平台,其目录结构都是一样的。
Cefclient:是一个示例程序,可以通过构建二进制的文件进行配置。该示例完整得展示了CEF广泛的功能性。创建CEF应用最简单的方法就是,在其基础上删除不需要的部分。
Cefsimple:是一个示例程序,可以通过构建二进制的文件进行配置。该示例通过创建一个浏览器窗口,简单展示了CEF的使用。
Debug:包含平台所需构建CEF的动态库(libcef)和其他的一些库。
Include:包含CEF所需的头文件。
Libcef_dll:包含libcef_dll_wrapper静态库的源码,该库提供CEF所需的C++API。
Release:包含平台所需构建CEF的动态库(libcef)和其他的一些库。
Resources:包含CEF应用所需的资源文件(只windows和linux使用)。包括.pak文件和一些平台依赖的文件。
C++Wrapper
libcef动态库提供C API让使用者不用关心CEF运行库和基础代码。libcef_dll_wrapper 工程把 C API 封装成 C++ API同时包含在客户端应用程序工程中,与 cefclient一样,源代码作为CEF二进制发布包的一部分共同发布。C/C++ API的转换层代码是由转换工具自动生成。
进程
CEF3使用多进程架构。
browser进程:主进程browser进程处理窗口创建、窗口绘制、网络交互以及大部分的主要逻辑。
render进程:Blink的渲染和js的执行,通常在分离的render(渲染)进程里。除此之外,render进程还会处理一些逻辑,例如js bindings和dom节点的访问。进程模型默认会为每个唯一源(协议+域)创建一个新的render进程。
其他进程:其他进程例如管理插件的进程以及处理合成加速的进程等都是按需创建。
主程序通常会多次启动独立的子进程。通过传递不同的命令行参数给CefExecuteProcess 函数实现的。如果主应用执行体比较大,加载时间花费比较长,宿主程序可以使用分离的可执行程序去运行这些进程。这种方式是通过初始化CEF时设置CefSettings.browser_subprocess_path参数实现的。具体详见
线程
CEF3的每个进程都包含多个线程,常用的线程如下:
TID_UI线程:该线程是browser进程的主线程。如果cef初始化时,设置CefSettings.multi_threaded_message_loop 为false,则该线程就是依附线程。
TID_IO线程:该线程在browser进程中处理进程间通信和网络通信。
TID_FILE线程:该线程在browser进程中与文件系统进行交互。
TID_RENDER线程:该线程时render进程的主线程。所有blink和V8交互必须在该线程执行。
事件循环:
CefRunMessageLoop是执行CEF自身的消息循环,CEF可以集成到外部应用的事件循环取代自己独立的消息循环,有两种方式可以实现:
1.周期性的调用CefDoMessageLoopWork()取代CefRunMessageLoop()。每次调用CefDoMessageLoopWork()都将处理一次CEF消息循环事件。使用这种方法需要注意,调用频率过少消息循环会饿死并影响browser的性能,调用频率过高会影响CPU的性能。
2.设置 CefSettings.multi_threaded_message_loop = true(windows平台有效)。这将导致browser的ui线程与依附执行体的线程分离,独立执行一个新的ui线程。这种方式CefDoMessageLoopWork()和CefRunMessageLoop()都不需要调用。在执行体中的线程需要调用CefInitialize() 和 CefShutdown() 。
网络层
通常情况下,CEF3的网络请求对宿主程序是透明的。对于应用程序希望更进一步接触到网络层,因此CEF3也提供了一些网络相关的函数。网络相关的回调可以发生在不同线程,注意文档说明并对你的数据进行线程安全保护。
请求响应
CEF3支持两种网络请求处理方式。 一种方法是实现一个Schemehandler,用来处理已经注册指定的源(协议+源)请求。另一种方式可以根据应用需要自行拦截任意的请求。
尽量使用http协议代替自定义协议来避免一系列潜在得问题。如果选择使用自定义协议,你需要使用CEF进行注册来实现希望的处理方式。如果希望自定义协议行为与HTTP类似,你需要将其注册为”标准”协议。如果希望自定义协议可以发送跨域请求,尽量使用HTTP协议来避免潜在问题。如果你希望使用自定义协议,必须要在所有进程实现 回调函数CefApp::OnRegisterCustomSchemes()。