CEF Render进程和Browser进程之间的通信,往往使用CefBrowser::SendProcessMessage()方法。由于CefBrowser 与CefFrame对象同时存在于browser与render进程中,所以不管在渲染(Render)进程还是浏览(Browser)进程中,都能调用到SendProcessMessage()方法。
所有render进程提供利用相同的消息传递方式:通过browser进程中的CefBrowserProcessHandler::OnRenderProcessThreadCreated()将消息传递给render进程中的CefRenderProcessHandler::OnRenderThreadCreated()。
从browser进程发到render进程的消息,被CefRenderProcessHandler::OnProcessMessageReceived()接收,从render进程发到browser进程的消息,被CefBrowserProcessHandler::OnProcessMessageReceived()接收。见下图:
SendProcessMessage
SendProcessMessage 是CefBrowser对象的一个方法,但是通信只能由Render->Browser或者Browser->Render不能再自己进程间传递。否则会出问题。
target_process目标进程只有两种:Render 或 Browser
///
// Existing process IDs.
///
typedef enum {
///
// Browser process.
///
PID_BROWSER,
///
// Renderer process.
///
PID_RENDERER,
} cef_process_id_t;
创建基本流程:
- 调用CefProcessMessage::Create创建Message
- 设置Message的参数,一个下标保存一种数据
- 发送消息SendProcessMessage
//创建消息对象
CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("test");
//设置参数列表
CefRefPtr<CefListValue> args = message->GetArgumentList();
args->SetString(0, L"string_0");
args->SetString(1, L"string_1");
args->SetString(2, L"string_2");
//发送消息
browser->SendProcessMessage(target_process, message);
ProcessMessage消息处理
Browser进程
对于Browser进程,则需要重写CefClient的OnProcessMessageReceived函数。Demo代码如下:
bool CBrowserHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process, CefRefPtr<CefProcessMessage> message)
{
CEF_REQUIRE_UI_THREAD();
CefString name = message->GetName();
CefRefPtr<CefListValue> args = message->GetArgumentList();
if (name == "test")
{
CefString str = args->GetString(0);
std::wstring strParams;
strParams += args->GetString(0).ToWString();
strParams += args->GetString(1).ToWString();
strParams += args->GetString(2).ToWString();
CString strJs;
strJs.Format(_T("alert('browser %s')"), strParams.c_str());
browser->GetMainFrame()->ExecuteJavaScript(strJs.GetBuffer(0), "", 0);
return true;
}
return false;
}
Render进程
对于Render进程,则需要重写CefRenderProcessHandler的OnProcessMessageReceived函数。Demo代码如下:
bool CRenderApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message)
{
CEF_REQUIRE_RENDERER_THREAD();
CefString name = message->GetName();
CefRefPtr<CefListValue> args = message->GetArgumentList();
if (name == "test")
{
CefString str = args->GetString(0);
std::wstring strParams;
strParams += args->GetString(0).ToWString();
strParams += args->GetString(1).ToWString();
strParams += args->GetString(2).ToWString();
CString strJs;
strJs.Format(_T("alert('render %s')"), strParams.c_str());
browser->GetMainFrame()->ExecuteJavaScript(strJs.GetBuffer(0), "", 0);
//发送一个消息给Browser
CefRefPtr<CefProcessMessage> browser_message = CefProcessMessage::Create("test");
CefRefPtr<CefListValue> browser_arg = browser_message->GetArgumentList();
browser_arg->SetString(0, "hellow0");
browser_arg->SetString(1, "hellow1");
browser_arg->SetString(2, "hellow2");
browser->SendProcessMessage(PID_BROWSER, browser_message);
return true;
}
return false;
}