0

在 GWT 中,为了在托管模式“开发模式”下运行应用程序,您将 get.codesvr 参数附加到 url,如下所示。

/?gwt.codesvr=127.0.0.1:9997

第一个问题是我想知道 GWT 如何知道何时启动 JVM 实例来提供 .class 文件而不是编译的 JavaScript 文件?我似乎无法找到 GWT 在开发模式下的工作方式。我确实在 com.google.gwt.devDevMode 中找到了 main()。这个 main() 怎么调用?

第二个问题在文档中说 GWT devmode 与 Jetty 服务器一起运行,但是我在浏览器中看到了实际的 JavaScript。这个码头服务器如何从客户端代码的 .class 文件中输出 JavaScript?

谢谢。

4

2 回答 2

4

所有的魔法都是通过 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 函数来返回控制权。)

于 2013-09-03T05:29:28.630 回答
2

添加gwt.codesvr到查询字符串显然是不够的。

首先,您启动 DevMode(com.google.gwt.dev.DevMode类),它启动一个嵌入式 Jetty 服务器(除非您通过-noserver参数禁用它)并且(更重要的是)侦听您的浏览器(默认为仅本地主机网络接口,在端口 9997) .

然后,您在浏览器中打开您的应用程序,并gwt.codesvr 指向DevMode 侦听的地址和端口。当*.nocache.js文件加载时,它会检测gwt.codesvr并加载devmode.html而不是你的*.cache.html. 该代码将加载您在浏览器中安装的 GWT 开发插件(或告诉您安装它),并引导它在gwt.codesvr查询字符串参数中指定的地址和端口连接到 DevMode。

这样,您的浏览器会与 DevMode 对话,后者会加载您的 Java 代码并在 JVM 中编译和运行它。正如 Suresh 已经指出的那样,GWT wiki中描述了该对话框的工作原理。

于 2013-09-03T08:53:49.637 回答