javascript — Фоновый процесс для встроенной функции в Chromium Embedded Framework

Я тестирую программу CEF3 на Visual Studio 2013 (C ++) и Windows 8.1.

Я хочу обработать нативную функцию, вызванную из JavaScript. Однако пока выполняется нативная функция, браузер зависает. 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;
}

2

Решение

Проблема в том, что обратный вызов JavaScript происходит на Процесс рендеринга клиента CEF. Этот процесс непосредственно отвечает за все взаимодействие с пользователем, клики, выполнение JS и тому подобное. Даже если вы публикуете в другой теме (в том же процессе), это не имеет большого значения, как кажется.

Что вы хотели бы сделать, это отправить это на Процесс браузера и сделайте обработку там. CEF3 часто задаваемые вопросы покрывает это сообщение, если у вас не было необходимости делать это раньше:

[…] Как передать информацию между браузером и процессами рендеринга в CEF3?

Для предоставления информации динамически используйте сообщения процесса (CefProcessMessage), которые связаны с конкретным CefBrowser экземпляр и отправляются с использованием CefBrowser::SendProcessMessage() метод. […] Сообщение, отправленное процессом рендеринга в процесс браузера, поступит в CefClient::OnProcessMessageReceived(), […]

Похоже, что это довольно большое дело в Adobe Brackets-Shell (достаточно популярном WebIDE с открытым исходным кодом, который использует CEF3) — их руководство по расширениям V8 проходит через это очень хорошо.

Всякий раз, когда вызывается нативная функция, AppShellExtensionHandler::Execute() вызывается. Этот код выполняется в процессе рендеринга, поэтому здесь должен выполняться только самый простой код расширения. Только для скобок getElapsedMilliseconds() обрабатывается здесь. Все остальные вызовы передаются процессу браузера через CefProcessMessage,

AppShellExtensionHandler упомянутое здесь эквивалентно вашему AppExtensionHandler, Я очень рекомендую просмотреть их код для обработки расширений — это было сделано довольно элегантно. Справедливое предупреждение: я профессионально связан с Adobe, хотя Brackets.io — предприятие с открытым исходным кодом.

Надеюсь, это поможет — ура!

4

Другие решения

Посмотрите на этот пост. Отлично работает. Решает все мои JS для нативных проблем и использует структурированный подход передачи параметров … и он точно решает проблему, с которой вы тоже сталкиваетесь … вам просто нужно создать пользовательский поток (Task) для обработки вещей в фоновом режиме …

JS на родной через V8Context — асинхронно!

Я проверил это сам, и это работает очень хорошо .. если я что-то упустил …

Хотя в посте описывается C #, перевести его на C ++ будет очень просто

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector