Chromium Embedded Framework中本机功能的后台流程 [英] Background process on the native function at Chromium Embedded Framework

查看:246
本文介绍了Chromium Embedded Framework中本机功能的后台流程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我想处理从JavaScript调用的本机函数。但是,在执行本机功能时,浏览器会冻结。 PostTask也没有效果。



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



是不是有异步处理函数的好方法?

  CefSettings设置; 
settings.single_process = true;

void App :: OnContextCreated(
CefRefPtr< CefBrowser>浏览器,
CefRefPtr< CefFrame>帧,
CefRefPtr< CefV8Context>上下文)
{
CoInitializeEx(NULL,COINIT_MULTITHREADED);

//检索上下文的窗口对象。
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())返回false;

if(name ==execNative){
Sleep(10000); //重工序

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

返回true;
}


解决方案

问题在于javascript回调发生在CEF客户端的渲染过程上。该过程直接负责所有用户交互,点击,JS执行等。即使你发布到另一个线程(在同一个过程中),它似乎没有产生巨大的差异。



你想要做的是将它发送到浏览器进程并在那里进行处理。 CEF3常见问题解答涵盖此通讯,如果您有之前没有必要这样做:


[...] 如何在浏览器和渲染进程之间发送信息CEF3?



要提供动态信息,请使用与特定关联的流程消息( CefProcessMessage CefBrowser 实例,并使用 CefBrowser :: SendProcessMessage()方法发送。 [...]从渲染过程发送到浏览器进程的消息将到达 CefClient :: OnProcessMessageReceived()。 [...]


似乎这在Adobe Brackets-Shell(一个使用相当流行的开源WebIDE)中相当大CEF3) - 他们的 V8扩展指南非常适合。


每当调用本机函数时, AppShellExtensionHandler :: Execute()是调用。此代码在渲染过程中运行,因此此处只应执行最简单的扩展代码。对于Brackets,此处仅处理 getElapsedMilliseconds()。所有其他调用都通过 CefProcessMessage 传递给浏览器进程。


这里提到的 AppShellExtensionHandler 相当于你的 AppExtensionHandler 。我强烈建议您通过他们的代码进行扩展处理 - 它已经非常优雅地完成了。 公平警告:虽然Brackets.io是一家开源企业,但我与Adobe有着密切的关系。



希望这会有所帮助 - 干杯! / p>

I'm testing a CEF3 program on Visual Studio 2013(C++) and Windows 8.1.

I want to process the native function called from JavaScript. However, while the native function is executing, a browser freezes. PostTask is not effective, either.

In the case of a thread is made with CreateThread(Win32 API), it occurs an error when getting CefV8Value in the other thread.

Isn't there any good way of processing a function asynchronously?

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

解决方案

The issue is that the javascript callback happens on the Render process of the CEF Client. This process is directly responsible for all user interaction, the clicks, JS execution, and the like. Even if you post to another thread (in the same process), it's not making a huge difference it seems.

What you would want to do is send this over to the Browser process and do the processing there. The CEF3 Faqs covers this communication,in case you have not had need to do this before:

[...] 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(). [...]

Seems like this is quite a big deal in Adobe Brackets-Shell (a reasonably popular open source WebIDE that uses CEF3) - their guide to V8 extensions goes through this very nicely.

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.

The AppShellExtensionHandler mentioned here is equivalent to your AppExtensionHandler. I would highly recommend going through their code for extension handling - it's been done quite elegantly. Fair Warning: I am related to Adobe professionally, though Brackets.io is an open-source venture.

Hope this helps - Cheers!

这篇关于Chromium Embedded Framework中本机功能的后台流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆