我正在为类似GWT的框架开发自己的DevMode实现。这个DevMode是 像GWT的旧DevMode一样,因为GWT teavm不想这样做,因此将被弃用 支持浏览器插件。另一个原因是NPAPI已从最新版Google Chrome中删除。 所以我的DevMode实现有自己的谷歌浏览器扩展,完全写入 JavaScript并通过WebSocket与服务器通信。
DevMode的主要目标是在Java IDE中启用Java代码的调试。它运行Java代码 在JVM中,当JVM尝试执行JavaScript代码时,它会将其远程传输到浏览器 扩展,执行JavaScript并返回结果。但事情稍微多一些 在实践中很难,因为JVM可以将回调传递给JavaScript,因此存在双向性 JVM和浏览器扩展之间的消息流,在任何嵌套深度。考虑以下 乒乓:
public class PingPong {
public native void ping(int count) /*-{
console.log("Before ping %d", count);
this.pong(count - 1);
console.log("After ping %d", count);
-}*/;
public void pong(int count) {
System.out.println("Before pong " + count);
ping(count - 1);
System.out.println("After pong " + count);
}
}
当ping
调用pong
时,它应该等到JVM收到消息,处理它并发送响应
背部。此外,JVM再次调用ping
,依此类推。但是,WebSocket API是异步的。
此外,我们不能阻止JVM响应,因为JVM可能会再次调用JavaScript。
所以我在扩展程序中使用远程调试协议。
当扩展程序收到调用JavaScript方法的命令时,
它将Runtime.callFunctionOn
命令发送到调试器API。当Java传递回调时
扩展,它创建以下代理功能:
function() {
var params = [];
for (var i = 0; i < arguments.length; ++i) {
params.push(arguments[i]);
}
return sendMessage({
type : "invoke-method",
methodName : methodName,
args : params
});
}
其中sendMessage
是:
function sendMessage(message) {
sentMessage = message;
while (sentMessage != null) {
debugger;
}
return receivedMessage;
}
此外,扩展程序会监听Debugger.paused
通知。当收到通知时
扩展将消息发送到JVM并等待响应。收到回复后,
扩展程序集receivedMessage
,清除sentMessage
并将Debugger.resume
发送给调试程序。
不幸的是,我有两个主要问题。首先,我打电话时
element.addEventListener("click", callback)
从JVM ,然后单击元素,Debugger.paused
按预期方式进行。
但是当我通过RDP阅读sentMessage
时,我得到objectId
与我传递的不同
addEventListener
。对象ID是否在Google Chrome调试器API中持久存在?
第二个问题是速度。 RDP往返每次呼叫需要10-20毫秒。还有另一个吗? 使用Google Chrome扩展程序API阻止执行脚本的方法?另外,我不仅想要 阻止,但要进入嵌套事件循环,因为JVM回调可能会再次调用JavaScript。