我正在 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 specificCefBrowser
instance and are sent using theCefBrowser::SendProcessMessage()
method. [...] A message sent from the render process to the browser process will arrive inCefClient::OnProcessMessageReceived()
. [...]
这在 Adobe 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, onlygetElapsedMilliseconds()
is handled here. All others calls are passed to the browser process via aCefProcessMessage
.
这里说的AppShellExtensionHandler
相当于你的AppExtensionHandler
。我强烈建议通过他们的代码进行扩展处理 - 它已经完成得非常优雅。 公平警告:尽管 Brackets.io 是一家开源企业,但我在专业上与 Adobe 有关。
希望这有帮助 - 干杯!
关于javascript - Chromium Embedded Framework 原生函数的后台进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23244592/