Meteor:从服务器metod调用返回时的长延迟

时间:2017-04-05 08:19:46

标签: meteor

我做了Meteor.call。我看到服务器执行其代码并在不到一秒钟内完成。然后,每隔一段时间,客户端等待很长时间才能收到响应。这是在本地发生的,因此它与任何互联网连接问题都没有关系。响应由一个非常小的对象组成,所以我也不认为它是一个JSON解析问题。

这里的要点是服务器已完成并已返回其响应...但客户端最多只能在几分钟内收到它。

服务器代码:

Meteor.call("findComments", ne, sw, filter, timezoneOffset, function(err, comments) {
    console.log("comments = " + comments);
    // ... and we're back
}

客户代码:

var WebSocketTransport = SockJS.websocket = function(ri, trans_url) {                                             // 1263
    var that = this;                                                                                              // 1264
    var url = trans_url + '/websocket';                                                                           // 1265
    if (url.slice(0, 5) === 'https') {                                                                            // 1266
        url = 'wss' + url.slice(5);                                                                               // 1267
    } else {                                                                                                      // 1268
        url = 'ws' + url.slice(4);                                                                                // 1269
    }                                                                                                             // 1270
    that.ri = ri;                                                                                                 // 1271
    that.url = url;                                                                                               // 1272
    var Constructor = _window.WebSocket || _window.MozWebSocket;                                                  // 1273
                                                                                                                  // 1274
    that.ws = new Constructor(that.url);                                                                          // 1275
    that.ws.onmessage = function(e) {     <-- RIGHT HERE IS WHERE IT STOPS                                                                          // 1276
        that.ri._didMessage(e.data);                                                                              // 1277
    };                                                                                                            // 1278
    // Firefox has an interesting bug. If a websocket connection is                                               // 1279
    // created after onunload, it stays alive even when user                                                      // 1280
    // navigates away from the page. In such situation let's lie -                                                // 1281
    // let's not open the ws connection at all. See:                                                              // 1282
    // https://github.com/sockjs/sockjs-client/issues/28                                                          // 1283
    // https://bugzilla.mozilla.org/show_bug.cgi?id=696085                                                        // 1284
    that.unload_ref = utils.unload_add(function(){that.ws.close()});                                              // 1285
    that.ws.onclose = function() {                                                                                // 1286
        that.ri._didMessage(utils.closeFrame(1006, "WebSocket connection broken"));                               // 1287
    };                                                                                                            // 1288
};                                                                                                                // 1289

我可以在这个&#34; Meteor.call&#34;中加入一个断点。客户端代码中的行,以及回调中的行。我看到&#34;现在回来......&#34;在服务器上,然后....没有。我等了几分钟,然后我看到好的结果在回调中回到了客户端。

此行为可以在Chrome以及Android和iOS上已安装的应用中看到。它很少发生,但极具破坏性,我们无法隔离导致这种情况的任何特定条件。

怎么做??

编辑:

大约2分钟后,客户端最终会进入回调状态。在此期间,CPU处于空闲状态。我还用一个简单的服务器调用来测试它,该服务器调用不带任何参数,并且在服务器上什么都不做......同样的效果。

因此,如果我在客户端上停止执行以查看他在此期间的操作,则会在此函数中停止,在lib / trans-websocket.js中:

bubbles    :    false
cancelBubble    :    false
cancelable    :    false
composed    :    false
currentTarget    :    WebSocket
data    :    "a["{\"msg\":\"updated\",\"methods\":[\"64\"]}"]"
defaultPrevented    :    false
eventPhase    :    2
isTrusted    :    true
lastEventId    :    ""
origin    :    "ws://localhost:3000"
path    :    Array[0]
ports    :    null
returnValue    :    true
source    :    null
srcElement    :    WebSocket
target    :    WebSocket
timeStamp    :    17400.095
type    :    "message"
__proto__    :    MessageEvent

奇怪的是,我在此代码中放置的任何断点都将被忽略。但我可以检查MessageEvent e的值:

function drop(ev) {
    ev.preventDefault();
    var divRatio = $('#div').width() / $('#div').height();
    var imageRatio = $('#div').width() / $('#div').height();
    if (imageRatio <= divRatio) {
        ev.target.appendChild(document.getElementById(data));
    }    
}

2 个答案:

答案 0 :(得分:0)

尝试将您的函数放在try / catch中,如下所示:

myFunction() {

      try {
             ...  
          } catch(e) {
              throw new Meteor.Error(e.code,e);
          }
}

然后在Meteor.call中捕获错误。也许在服务器上发生错误。

答案 1 :(得分:0)

这适用于仍在寻找此问题解决方案的任何人。 正如它在 Meteor 文档中提到的那样。

<块引用>

一旦方法在服务器上运行完毕,它会向客户端发送一条结果消息,其中包含在步骤 2 中生成的方法 ID,以及返回值本身。客户端存储它以备后用,但尚未调用 Method 回调。如果您将 onResultReceived 选项传递给 Meteor.apply,则会触发该回调。

参考:https://guide.meteor.com/methods.html#advanced-boilerplate

因此,如果您希望在服务器方法返回值后触发回调,那么您可以使用带有 onResultReceived 选项的 Metor.apply 方法。

Meteor.apply(
  "findComments",
  [ne, sw, filter, timezoneOffset],
  {
    onResultReceived: function(err, comments) {
      console.log("comments = " + comments);
      // ... and we're back
    }
  }

即使我在延迟时间上挣扎,但在超过它的瞬间之后。