3.3 CEF进程间通讯
3.3.1 进程间通讯函数
3.3.2 进程通讯实例
3.3.3 CEF指定frame通讯
3.3 CEF进程间通讯
3.3.1 进程间通讯函数
CEF有Browser进程和Renderer进程,进程之间可以相互通信。
发送消息Browser进程和Renderer进程都是一样的,使用CefBrowser::SendProcessMessage() ,SendProcessMessage第一个参数是CefProcessId,是一个枚举类型,给Browser进程发送,就用PID_BROWSER,给Render进程发送,就用PID_RENDERER。
typedef enum {
///
// Browser process.
///
PID_BROWSER,
///
// Renderer process.
///
PID_RENDERER,
} cef_process_id_t;
Render进程这边, 重写CefRenderProcessHandler::OnProcessMessageReceived()
Browser进程这边,重写CefClient::OnProcessMessageReceived()这个方法来处理跨进程消息。
3.3.2 进程通讯实例
(1)renderer进程发送消息
CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("login_msg");
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg->GetArgumentList();
// Populate the argument values.
args->SetSize(2);
args->SetString(0, strUser);
args->SetString(1, strPassword);
// Send the process message to the browser process.
CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, msg);
(2)Browser进程这边,重写CefClient::OnProcessMessageReceived()这个方法来处理跨进程消息。接收到消息之后再回复消息。
bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message)
{
const std::string& messageName = message->GetName();
if (messageName == "login_msg")
{
// extract message
CefRefPtr<CefListValue> args = message->GetArgumentList();
CefString strUser = args->GetString(0);
CefString strPassword = args->GetString(1);
TCHAR szLog[256] = { 0 };
_stprintf_s(szLog, 256, _T("BrowserProcess, user - %s, password - %s\r\n"), strUser.c_str(), strPassword.c_str());
OutputDebugString(szLog);
//send reply to render process
CefRefPtr<CefProcessMessage> outMsg = CefProcessMessage::Create("login_reply");
// Retrieve the argument list object.
CefRefPtr<CefListValue> replyArgs = outMsg->GetArgumentList();
// Populate the argument values.
replyArgs->SetSize(1);
replyArgs->SetInt(0, 0);
// Send the process message to the renderer process.
browser->SendProcessMessage(PID_RENDERER, outMsg);
return true;
}
return false;
}
(3)Render进程这边, 重写CefRenderProcessHandler:: OnProcessMessageReceived()方法来处理来自Browser进程的消息。
bool ClientAppRenderer::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message)
{
const std::string& messageName = message->GetName();
if (messageName == "login_reply")
{
// extract message
CefRefPtr<CefListValue> args = message->GetArgumentList();
int status = args->GetInt(0);
OutputDebugString(status == 0 ? _T("Renderer process, login ok\r\n") : _T("Renderer process, login failed\r\n"));
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript("alert(‘Got Login Reply from Browser process‘)", frame->GetURL(), 0);
return true;
}
return false;
}
3.3.3 CEF指定frame通讯
一个网页有多个frame,有一个mainframe和多个subframe,发送消息时,将frame的id放入参数中一起发过去,接收时消息时,获取frameid,就可以实现指定frame通讯。因为frameid是一个int64类型的数据,所以发送时将它分解为两个int32
的高低位数据,接收数据时,再将两个int32的数据拼接成一个int64数据。
#define MAKE_INT64(int_low, int_high) \
((int64) (((int) (int_low)) | ((int64) ((int) (int_high))) << 32))
#define LOW_INT(int64_val) ((int) (int64_val))
#define HIGH_INT(int64_val) ((int) (((int64) (int64_val) >> 32) & 0xFFFFFFFFL))
// Sending the frame ID.
const int64 frame_id = frame->GetIdentifier();
args->SetInt(0, LOW_INT(frame_id));
args->SetInt(1, HIGH_INT(frame_id));
// Receiving the frame ID.
const int64 frame_id = MAKE_INT64(args->GetInt(0), args->GetInt(1));
CefRefPtr<CefFrame> frame = browser->GetFrame(frame_id);
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: