Chromium IPC機制舉例

原文詳見:http://www.bytekits.com/tsingchen/cef/ipc-example.html

IPC(Inter-Process Communication,進程間通信)

CEF提供了幾種IPC機制,現主要介紹一下Process Runtime Messages這種方式

發送消息

發送消息使用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進程。

接收消息

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 - %srn"), 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進程這邊, 重寫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 okrn") : _T("Renderer process, login failedrn"));
        CefRefPtr<CefFrame> frame = browser->GetMainFrame();
        frame->ExecuteJavaScript("alert('Got Login Reply from Browser process')", frame->GetURL(), 0);
        return true;
    }
    return false;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章