CEF 进程间消息传递

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;
}

运行结果如下:

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CAir2/article/details/85290766
CEF