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

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

我把那个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;
}

可以看到,上面的代码又给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;
}


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

其他参考文章:

时间: 2024-10-10 05:21:14

CEF中Browser进程与Render进程间通信的相关文章

CEF中禁止弹出浏览器窗口

使用CEF时,加载的网页,如果里面有链接,指定target="_blank",则会弹出一个新的浏览窗口.如果想禁掉,让新页面在当前浏览窗口中显示,可以在browser进程的handler里重写CefLifeSpanHandler的OnBeforePopup方法,用browser的mainFrame加载popup请求的url.代码如下: bool SimpleHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRe

Browser进程和浏览器内核(Renderer进程)的通信过程

看到这里,首先,应该对浏览器内的进程和线程都有一定理解了,那么接下来,再谈谈浏览器的Browser进程(控制进程)是如何和内核通信的, 这点也理解后,就可以将这部分的知识串联起来,从头到尾有一个完整的概念. 如果自己打开任务管理器,然后打开一个浏览器,就可以看到:任务管理器中出现了两个进程(一个是主控进程,一个则是打开Tab页的渲染进程),然后在这前提下,看下整个的过程:(简化了很多) Browser进程收到用户请求,首先需要获取页面内容(譬如通过网络下载资源),随后将该任务通过Renderer

CEF中访问修改HTML DOM元素

有时你可能想在C++代码中直接操作HTML中的某个元素,比如改变某个按钮的状态(文字.颜色)等,此时可以使用CEF提供的CefDomVisitor.CefDOMDocument.CefDomNode这三个类,包含cef_dom.h即可. 我们可以用它们完成下列任务: 使用DOM模型访问HTML的各种节点(Element.Attribute.Text.CDATA.Comment.Document等) 修改某个元素的属性 修改某个Text节点的值 下面简要说说各个类的用法. CefDOMDocume

Linux进程IPC浅析[进程间通信SystemV共享内存]

Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到自己的虚拟内存空间,所有用户空间的进程若要操作共享内存,都要将其映射到自己的虚拟内存空间中,通过映射的虚拟内存空间地址去操作共享内存,从而达到进程间的数据通信 共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容 本身不提供同

01python 中的进程(python并发编程)

00.进程 span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-s

Linux中的进程及进程控制

一.整体大纲 二.基础知识 1. 进程相关概念 1)程序和进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(cpu.内存.打开的文件.设备.锁....)     进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃(运行起来的)的程序,占用系统资源.在内存中执行.(程序运行起来,产生一个进程).     程序 → 剧本(纸) 进程 → 戏(舞台.演员.灯光.道具...),同一个剧本可以在多个舞台同时上演.同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)     如:同

Python程序中的进程操作-开启多进程(multiprocess.process)

目录 一.multiprocess模块 二.multiprocess.process模块 三.process模块介绍 3.1 方法介绍 3.2 属性介绍 3.3 在windows中使用process模块的注意事项 四.使用process模块创建进程 4.1 在Python中启动的第一个子进程 4.2 join方法 4.3 查看主进程和子进程的进程号 4.4 多个进程同时运行 4.5 多个进程同时运行,再谈join方法(1) 4.6 多个进程同时运行,再谈join方法(2) 4.7 通过继承Pro

110 python程序中的进程操作-开启多进程

之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序也是一个进程,那么我们也可以在程序中再创建进程.多个进程可以实现并发效果,也就是说,当我们的程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快.以我们之前所学的知识,并不能实现创建进程这个功能,所以我们就需要借助python中强大的模块. 一.multiprocess模块 仔细说来,multipro

112 python程序中的进程操作-进程之间进行通信(mulitiProcessing Queue队列)

一.进程间通信 IPC(Inter-Process Communication) IPC机制:实现进程之间通讯 管道:pipe 基于共享的内存空间 队列:pipe+锁的概念--->queue 二.队列(Queue) 2.1 概念-----multiProcess.Queue 创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递. Queue([maxsize])创建共享的进程队列. 参数 :maxsize是队列中允许的最大项数.如果省略此参数,则无大小限制