流星:从服务器方法调用返回时的长延迟 [英] Meteor: long latency when returning from server metod call

查看:20
本文介绍了流星:从服务器方法调用返回时的长延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I do a Meteor.call. I see the server execute its code and finish in less than one second. Then, every once in a while, the client waits a very long time to receive the response. This happens locally, so it isn't related to any internet connectivity issue. The response consists of a quite small object, so I don't think it's a JSON parsing issue, either.

这里的重点是服务器已经完成并返回了它的响应......但客户端在长达几分钟的时间内没有收到它.

The point here is that the server is finished and has returned its response... but the client does not receive it for up to several minutes.

服务器代码:

findComments : function(ne, sw, filter, timezoneOffset) {
    // ... do some Mongo queries and updates ... etc.  nothing too weird.

    console.log("returning now...");
    return result;
}

客户端代码:

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

我可以在客户端代码的Meteor.call"行和回调中放置一个断点.我在服务器上看到现在返回……",然后……什么也没有.我等了几分钟,然后我看到好的结果在回调中返回给客户端.

I can put a breakpoint in this "Meteor.call" line in the client code, and in the callback. I see "returning now..." on the server, and then.... nothing. I wait a couple minutes, and then I see the good result coming back to the client in the callback.

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

This behavior can be seen in Chrome, as well as on the installed app on Android and iOS. It happens rarely, but is extremely disruptive, and we are not able to isolate any particular conditions leading to this.

怎么办??

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

The client does eventually go into the callback, after about 2 minutes. During this time, the CPU is idle. I also tested this with a simple server call that takes no arguments and does nothing at all on the server... same effect.

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

So, if I stop execution on the client to see what he's up to during this time, it stops in this function, in lib/trans-websocket.js:

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

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

Oddly, any breakpoints I put in this code will be ignored. But I can examine the value of the MessageEvent e:

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

推荐答案

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

This is for anyone who is still looking for solution to this problem. As it it mentioned in Meteor docs.

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

Once the Method has finished running on the server, it sends a result message to the client with the Method ID generated in step 2, and the return value itself. The client stores this for later use, but doesn’t call the Method callback yet. If you pass the onResultReceived option to Meteor.apply, that callback is fired.

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

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

So if you want your call back to be triggered once the server method return the value then you can use Metor.apply method with the option onResultReceived.

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

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

Even I was struggling with the latency time but after doing above its instant.

这篇关于流星:从服务器方法调用返回时的长延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆