所有的魔法都是通过 Sockets 和浏览器插件完成的。
设计:进程外托管模式 (OOPHM)
这是必不可少的部分。
考虑以下 GWT 代码:
public class MyEntryPoint implements EntryPoint {
private static native int jsniMethod() /*-{
return 1;
}-*/;
public void onModuleLoad() {
jsniMethod();
}
}
JavaScript:浏览器插件发送带有模块名称的 LoadModuleMessage。
Java:托管模式服务器接收LoadModuleMessage,加载模块并调用相应EntryPoints中的onModuleLoad。在这种情况下,调用 MyEntryPoint::onModuleLoad。编译 MyEntryPoint 时,会发送一个 LoadJsniMessage 来为每个 JSNI 方法创建浏览器端 JavaScript 函数,然后在 onModuleLoad 调用 jsniMethod 时发送一个 InvokeMessage。
JavaScript:这是示例的关键部分。JavaScript 引擎当前正在等待它发送的 LoadModuleMessage 的返回,但它必须能够在同一线程上调用对 MyEntryPoint::jsniMethod 的调用。这是通过让线程在每次远程调用之后进入读取和调度例程来完成的。在这种情况下,线程接收 LoadJsniMessage 和 InvokeMessage 消息,调用 jsniMethod 并发送包含值 1 的 ReturnMessage。
Java:读取和调度例程接收 ReturnMessage 并知道从对 jsniMethod 的调用中返回。完全执行 onModuleLoad 方法后,它会发送 ReturnMessage 并退回到顶级读取和调度循环。(由于所有调用都源自浏览器的 UI 事件调度,因此只有托管模式服务器需要在空闲时间保持在读取和调度例程中。浏览器只需通过退出最初调用的 JavaScript 函数来返回控制权。)