首页 > 解决方案 > JS 执行时,CEF 渲染器进程不处理进程消息

问题描述

我正在将我的应用程序从单进程的 CEF1 升级到 CEF3,并且我正在处理一些进程同步问题。

我在我的应用程序中有这个 CEF 实现:

应用程序使用 CreateBrowser 创建浏览器。这样浏览器进程实际上就是我的应用程序进程。

然后我有一个作为浏览器子进程运行的 exe,我在调用 CefInitialize 时在设置中设置它。

我的进程实例化了我的应用程序类,它继承自 CefApp 和 CefRenderProcessHandler 并调用 CefExecuteProcess。然后在 OnContextCreated 上的客户端应用程序类中,我创建了一个带有函数的对象,这些函数由继承自 CefV8Handler 的自定义编写类处理。这样,当从网页 JS 调用该对象的函数时,它会转到 CefV8Handler::Execute,我通过 Execute() 的 retval 参数返回结果。

现在真正的问题是网页与我的应用程序交互,为此我需要在应用程序中定义的属性最终在我的渲染器进程的实现中结束。我通过从浏览器进程(我的应用程序属性所在的位置)向渲染器进程发送进程消息来实现这一点,在渲染器进程中我为这些属性保留缓存,并且我的 CefV8Handler 可以访问它们。

现在的问题是,当渲染器进程被 JS 执行阻塞时,只有在 JS 执行完成后才会调用 OnProcessMessageReceived,即使我在 JS 执行过程中发送了一条消息。如果我正在发送一个属性,而使用该属性的 JS 正在执行,这可能会导致问题。

只是一个非常简化的示例来帮助描述问题。我的网页中有一个按钮,它运行以下代码,运行大约 10 秒:

for(int i = 0; i < 10000000000; i++) {}
var prop = MyObj.Property
alert(prop);

所以我单击按钮开始执行该代码,然后在我的应用程序中执行更新属性的操作,这会导致浏览器进程使用新的属性值向渲染器进程发送进程消息,但是由于 JS 正在执行 OnProcessMessageReceived在渲染器端不调用。所以 prop 接收到一个旧的 Property 值,只有在代码执行后 OnProcessMessageReceived 才会在渲染器进程上调用,并且下一次调用 MyObj.Property 将返回一个新值。

现在我知道 JS 是单线程的,但是 CEF 显然不是,所以有什么解决方法吗?消息可以由渲染器进程上的任何未阻塞线程处理,然后在我的 CefV8Handler 中我可以从该线程读取值吗?或者任何其他向渲染器进程发送消息的方式,可以在被 JS 执行阻塞时进行处理?

附言

我确实意识到有一个异步解决方案,其中回调函数传递给我的函数,然后我的处理程序向浏览器进程发送一条消息,然后将带有属性值的消息发送回渲染器进程,然后我调用回调函数与结果。像这样的东西:

MyProp.GetProperty(
function(prop)
{
  code that does something with prop
});

但这需要一个与我的应用程序集成的第 3 方网站来更改他们的 JS 端,我想不惜一切代价避免这种情况,并且我希望他们能够像使用 CEF1 实现一样直接访问我的属性调用吸气剂:

var prop = MyObj.Property;

标签: javascriptchromium-embedded

解决方案


推荐阅读