CEF中Browser进程与Render进程间通信

本文介绍了在CEF框架中,如何实现Browser进程与Render进程之间的通信。通过CefProcessMessage和CefBrowser::SendProcessMessage(),在Render进程发送消息到Browser进程,并在Browser进程重写CefClient::OnProcessMessageReceived()来处理消息。同时,在Render进程端,通过重写CefRenderProcessHandler::OnProcessMessageReceived()接收并处理来自Browser的消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                       

https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage提到了CEF提供的Browser与Browser进程通信的几种机制,我实验了Process Runtime Messages这种方式,用到了CefProcessMessage和CefBrowser::SendProcessMessage()。

我是在CEF中JS与C++交互一文的基础上完成的,我们边说基本步骤,边给出关键代码。

 

foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。

    1. 发送消息

发送消息使用CefBrowser::SendProcessMessage() ,SendProcessMessage第一个参数是CefProcessId,给Browser进程发送,就用PID_BROWSER,给Render进程发送,就用PID_RENDERER。

我在Render进程发送消息的代码如下(ClientV8Handler的Execute方法内):

        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);
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

我把那个cef_js_integration示例中收到的登陆消息(Render进程)发送给Browser进程。

    1. 处理消息

Browser进程这边,重写CefClient::OnProcessMessageReceived()这个方法来处理跨进程消息。

以cef_js_integration为例,是在ClientHandler中重写了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;}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

可以看到,上面的代码又给Render进程发了个消息。

Render进程这边, 重写CefRenderProcessHandler::OnProcessMessageReceived()方法来处理来自Browser进程的消息,具体代码在ClientAppRender类中:

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;}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

好啦,这就是整个过程了。

其他参考文章:

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值