javascript - Chromium Embedded Framework 原生函数的后台进程

标签 javascript c++ multithreading chromium chromium-embedded

我正在 Visual Studio 2013(C++) 和 Windows 8.1 上测试 CEF3 程序。

我想处理从 JavaScript 调用的 native 函数。但是,当 native 函数正在执行时,浏览器会卡住。 PostTask 也无效。

如果一个线程是用CreateThread(Win32 API)创建的,在另一个线程中获取CefV8Value时会发生错误。

有没有什么好的异步处理函数的方法?

CefSettings settings;
settings.single_process = true;

void App::OnContextCreated(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefV8Context> context) 
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // Retrieve the context's window object.
    CefRefPtr<CefV8Value> object = context->GetGlobal();

    CefRefPtr<CefV8Handler> handler = new AppExtensionHandler(this);
    object->SetValue("execNative",
        CefV8Value::CreateFunction("execNative", handler),
        V8_PROPERTY_ATTRIBUTE_NONE);
}

bool AppExtensionHandler::Execute(const CefString& name,
    CefRefPtr<CefV8Value> object,
    const CefV8ValueList& arguments,
    CefRefPtr<CefV8Value>& retval,
    CefString& exception)
{
    CefRefPtr<CefBrowser> browser = CefV8Context::GetCurrentContext()->GetBrowser();
    if (!browser.get()) return false;

    if (name == "execNative") {
        Sleep(10000); // heavy process

        CefRefPtr<CefFrame> frame = browser->GetMainFrame();
        frame->ExecuteJavaScript(L"result(true)", frame->GetURL(), 0);
    }

    return true;
}

最佳答案

问题是 javascript 回调发生在 CEF 客户端的渲染进程上。这个过程直接负责所有用户交互、点击、JS 执行等。即使您发布到另一个线程(在同一进程中),看起来也没有太大的不同。

您要做的是将其发送到浏览器进程 并在那里进行处理。 CEF3 Faqs涵盖此通信,以防您之前不需要这样做:

[...] How do I send information between the browser and render processes in CEF3?

To provide information dynamically use process messages (CefProcessMessage) which are associated with a specific CefBrowser instance and are sent using the CefBrowser::SendProcessMessage() method. [...] A message sent from the render process to the browser process will arrive in CefClient::OnProcessMessageReceived(). [...]

这在 Adob​​e Brackets-Shell(一种相当流行的使用 CEF3 的开源 WebIDE)中似乎是一件大事 - 他们的 guide to V8 extensions非常顺利地完成了这一过程。

Whenever a native function is called, AppShellExtensionHandler::Execute() is invoked. This code runs in the render process, so only the most trivial extension code should be executed here. For Brackets, only getElapsedMilliseconds() is handled here. All others calls are passed to the browser process via a CefProcessMessage.

这里说的AppShellExtensionHandler相当于你的AppExtensionHandler。我强烈建议通过他们的代码进行扩展处理 - 它已经完成得非常优雅。 公平警告:尽管 Brackets.io 是一家开源企业,但我在专业上与 Adob​​e 有关。

希望这有帮助 - 干杯!

关于javascript - Chromium Embedded Framework 原生函数的后台进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23244592/

相关文章:

javascript - 用于在页面上放置永久和临时 CSS 的自定义标签

javascript - 重写下划线交集——理解参数数组

c++ - 通过函数传递模板参数时出错

python - 使用 Kafka 在应用程序上打开太多文件错误

javascript - AngularJS:数据绑定(bind)模式 - 仅在单击 "Save"时保存更改,或者在单击 "Cancel"时忘记更改

javascript - 需要帮助让我的 Angular Directive(指令)发挥作用

c++ - "number>>1"中的 "binary(number >> 1)"是什么意思(十进制转二进制)

c++ - C++ 中的成员函数模板和重载 operator()

java - 在一个 Servlet 中同时处理

java - Camel 线程池查询