使用PubNub进行GWT脚本注入失败

时间:2012-10-10 19:37:54

标签: gwt pubnub

GWT的新手,但到目前为止我都喜欢它。我确实有一个容易重现的问题。这对我来说是个大问题,因为我想为PubNub创建一个GWT模块 - 我们内部使用的实用程序。

我创建了一个测试封装的演示项目,我发现ScriptInjector / Pubnub有一个有趣的问题。

首先,我按照PubNub说明进行操作。注意:我已将我的密钥包含在我的测试帐户中。随意使用它们。

按照说明我将这两项放在GWT项目的html文件中(指定了我的密钥):

<div pub-key="pub-b8b75fbd-c4cf-4583-bab9-424af7a7f755" sub-key="sub-5e843c94-1193-11e2-bba9-b116c93082cf" ssl="off" origin="pubsub.pubnub.com" id="pubnub"></div>
<script src="http://cdn.pubnub.com/pubnub-3.1.min.js"></script>

当我这样做时,我可以使用JSNI来访问pubnub。一切都很好。

如果我在这里删除标记并使用以下代码注入脚本,那么什么是行不通的。我知道脚本注入是因为我可以看到成功消息,我可以在Chrome中的Developer工具中看到该脚本。

          ScriptInjector.fromUrl("http://cdn.pubnub.com/pubnub-3.1.js").setCallback(
                  new Callback<Void, Exception>() {
                     public void onFailure(Exception reason) {
                       Window.alert("Script load failed.");
                     }
                     public void onSuccess(Void result) {
                       Window.alert("Script load success.");
                     }
                  }).inject();

我觉得这必须以某种方式与使用延迟脚本访问DOM相关,或者因为脚本不是DOM的一部分。它试图访问设置div,它无法...(只是我的猜测)

有什么想法?我需要将项目移出html文件,因为我需要模块化这个项目以便在其他更大的项目中使用。任何帮助将不胜感激。

(PS,我也尝试过创建html小部件,然后在EntryPoint中添加它们。这也会根据我在Chrome中的Developer Tools中的浏览情况将标签添加到页面中,但是当ScriptInjector失败时它无法正常工作。 )

编辑:这是一个简单的项目,我可以用来演示问题:

html文件:

结束体标记上方的

<div pub-key="pub-b8b75fbd-c4cf-4583-bab9-424af7a7f755" sub-key="sub-5e843c94-1193-11e2-bba9-b116c93082cf" ssl="off" origin="pubsub.pubnub.com" id="pubnub"></div>
<script src="http://cdn.pubnub.com/pubnub-3.1.min.js"></script>
<script src="pubnubWrapper.js"></script>

pubnubWrapper.js(基本上是pubnub网站上的内容):

function subToPubNub(){
    PUBNUB.subscribe({
        channel    : "hello_world",      // CONNECT TO THIS CHANNEL.
 
        restore    : false,              // STAY CONNECTED, EVEN WHEN BROWSER IS CLOSED
                                         // OR WHEN PAGE CHANGES.
 
        callback   : function(message) { // RECEIVED A MESSAGE.
            alert(message);
        },
 
        disconnect : function() {        // LOST CONNECTION.
            alert(
                "Connection Lost." +
                "Will auto-reconnect when Online."
            )
        },
 
        reconnect  : function() {        // CONNECTION RESTORED.
            alert("And we're Back!")
        },
 
        connect    : function() {        // CONNECTION ESTABLISHED.
 
            PUBNUB.publish({             // SEND A MESSAGE.
                channel : "hello_world",
                message : "Hi from PubNub."
            })
 
        }
    })
}

ScriptTest.java:

public class ScriptTest implements EntryPoint {
    public void onModuleLoad() {
        //add a button to sub to pubnub
        Button subButton = new Button("Sub");
        //add the event handler for button
        subButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                //sub to pubnub
              callSub();
            }
          });
        RootPanel.get().add(subButton);
    }
    public native void callSub() /*-{
        //call my wrapper to pubnub
        $wnd.subToPubNub();
    }-*/;
}

这一切都按原样运作。

如果从html文件中删除pubnub脚本并使用脚本注入器添加它,则会失败。如果将脚本添加到gwt.xml文件中,则会失败。

任何想法?

1 个答案:

答案 0 :(得分:0)

您可以发布您的JSNI代码吗? 我打赌你通过$wnd变量访问PubNub吧? 如果您将脚本标记放在模块的xml文件中,则pubnub代码将加载到主机的页面窗口中(您可以使用Chrome DeveloperTools查看)。

默认情况下,

ScriptInjector不会在GWT命名空间中加载它。 因此,为了将其加载到主机的窗口命名空间中,您必须将TOP_WINDOW传递给ScriptInjector

ScriptInjector.fromUrl("http://cdn.pubnub.com/pubnub-3.1.js").setCallback(
    new Callback<Void, Exception>() {
        public void onFailure(Exception reason) {
            Window.alert("Script load failed.");
        }
        public void onSuccess(Void result) {
            Window.alert("Script load success.");
        }
}).setWindow(ScriptInjector.TOP_WINDOW).inject();