还是按照以往方式,首先摆出问题:
(1)Renderer进程如何发送消息给Browser进程
(2)Browser进程如何发送消息给Renderer进程
围绕以上问题,在我原有的代码(http://download.csdn.net/detail/lixiang987654321/9602430)上回答以上两个问题,以下我们做一个简单的功能Render给Browser发一个消息,然后Browser验证后回复一个消息(cef中PID_BROWSER代表Browser浏览器进程,PID_RENDER代表Render进程):
(1)Renderer发送消息给Browser
通过我前一篇文章知道js引擎是运行在Renderer进程中的,在cefv8handler中js的处理函数中我们将函数名发送给browser进程,让其验证改函数,然后回复验证结果给Renderer进程,那么在Renderer中我们发送一个消息给Browser:
- bool CV8JsHandler::Execute(const CefString& func_name,
- CefRefPtr<CefV8Value> object,
- const CefV8ValueList& arguments,
- CefRefPtr<CefV8Value>& retval,
- CefString& exception)
- {
- // send message to browser process that method began to execute
- <span style="color:#ff0000;"> CefRefPtr<CefProcessMessage> objMsg = CefProcessMessage::Create(_T("msg_from_render"));
- CefRefPtr<CefListValue> arglist = objMsg->GetArgumentList();
- arglist->SetString(0, /*CefV8Value::CreateString()*/func_name);
- CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, objMsg);</span>
- if (func_name == _T("addFunction"))
- {
- int32 nSum = 0;
- for (size_t i = 0; i < arguments.size(); ++i)
- {
- if(!arguments[i]->IsInt())
- return false;
- nSum += arguments[i]->GetIntValue();
- }
- retval = CefV8Value::CreateInt(nSum);
- return true;
- }
- else if (func_name == _T("hehe"))
- {
- retval = CefV8Value::CreateString(_T("hehe hehe!"));
- return true;
- }
- else
- {
- return false;
- }
- }
(2)Browser回复对应消息
每一个Browser都有一个CefClient,cefclient实现所有消息或事件处理接口处理浏览器的所有事件,所以cefclient是运行在browser中的事件处理器,我们在Cefclient的实现中实现OnProcessMessageReceived接口,处理来自其他进程的消息:
- bool CCefBrowserEventHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
- CefProcessId source_process,
- CefRefPtr<CefProcessMessage> message) OVERRIDE
- {
- if (message->GetName() == _T("msg_from_render"))
- {
- CefRefPtr<CefListValue> argList = message->GetArgumentList();
- CefString strFunctionName = argList->GetString(0);
- bool bAllow = false;
- if (strFunctionName == _T("addFunction"))
- {
- bAllow = true;
- }
- CefRefPtr<CefProcessMessage> msg_back = CefProcessMessage::Create(_T("func_back"));
- msg_back->GetArgumentList()->SetString(0, strFunctionName);
- msg_back->GetArgumentList()->SetBool(1, bAllow);
- browser->SendProcessMessage(PID_RENDERER, msg_back);
- return true;
- }
- return false; // has handle for the message
- }
(3)Renderer处理回复
在Render进程处理器中处理OnProcessMessageReceived接口,检查回复:
- bool CCefBrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
- CefProcessId source_process,
- CefRefPtr<CefProcessMessage> message)
- {
- if (message->GetName() == _T("func_back"))
- {
- // extract message
- CefRefPtr<CefListValue> args = message->GetArgumentList();
- CefString strFunctionName = args->GetString(0);
- bool bAllow = args->GetBool(1);
- CString strMsg;
- strMsg.Format(_T("alert('function %s status %d')"), strFunctionName.c_str(), bAllow);
- browser->GetMainFrame()->ExecuteJavaScript((LPCTSTR)strMsg, browser->GetMainFrame()->GetURL(), 0);
- return true;
- }
- return false;
- }
关于CEF中进程通信很简单,我就说道这里,截图如下:
browser中收到render消息:
browser回复消息到render中,render收到结果:
browser中收到render消息:
browser回复消息到render中,render收到结果:
实例代码:http://download.csdn.net/detail/lixiang987654321/9602615