【问题标题】:long-poll jQuery.ajax() fails to callback after phone sleeps?手机休眠后长轮询jQuery.ajax()无法回调?
【发布时间】:2016-03-24 07:01:26
【问题描述】:

我的网络应用程序使用“长轮询”方法来及时了解来自我的服务器的最新数据。服务器仅在有新数据时才响应,这可能相隔数分钟。 (这是一个供暖控制系统,只有在室温变化或有人更改设置时才能看到更新)。

var version = "0";
function updater() {
    $.ajax({
        type: "POST",
        url: "/listen",
        data: version,
        success: function (data) {
            version = handleUpdates(data);
            updater();
        },
        error: function () {
            setTimeout(updater, 1000);
        }
    });
}

它在桌面浏览器和手机上都可以正常工作,但有一种情况除外。我发现在带有 Chrome 的安卓手机上,手机进入睡眠状态超过 10 分钟后会发生一些奇怪的事情。发布请求似乎已被删除,我认为这是合理的,因为手机处于睡眠状态。在 Chrome 调试器的网络选项卡中,POST 请求的状态文本显示为(已取消)。

问题是当我在请求被取消时唤醒手机时,既没有调用success() 也没有调用error() 函数,并且我的网络应用程序永远不会更新。 $.ajax() 违背了承诺给我回电话。

该问题仅发生在某些设备上。通过向朋友借用设备,我已经能够进行一些临时测试。到目前为止,我只在安卓手机上看到过这个问题。但不是手机连接到充电器。我没有在任何平板电脑、苹果设备或 Windows PC 上看到它。

我尝试在 ajax 设置中添加超时:

     timeout: 120 * 1000,

这很有帮助,因为 error() 函数最终会在唤醒后 2 分钟内被调用。但我希望用户在 1 或 2 秒内看到更新。我不想让超时时间这么短,因为它会造成不必要的服务器流量。

我还尝试通过在Can any desktop browsers detect when the computer resumes from sleep? 中描述的一秒 setInterval 中查找延迟来检测设备是否处于睡眠状态。 当我检测到唤醒时,我 abort() 发布并开始另一个。这在大多数情况下都有帮助。但事实证明是不可靠的。有时时间事件似乎在睡眠期间保持正常滴答作响,并且发布请求无论如何都会被取消。而且它感觉不像是一个可靠的解决方案。

我正在使用最新版本的 jQuery:(2.1.2) 和 Chrome (47)。

【问题讨论】:

  • 尝试全局存储当前的promise,然后当你进入这个失败状态时,检查promise的.state()。它包含什么?如果它包含“待定”以外的任何内容,您可以将它与@spozun 的解决方案结合使用,以便在睡眠期后重新启动,而不会不必要地取消请求。

标签: javascript jquery ajax google-chrome long-polling


【解决方案1】:

我过去曾遇到过当手机进入睡眠状态时 JavaScript 调用会暂停的问题。我最终得到的解决方案是使用window.setInterval(),它似乎暂停了,但当手机被唤醒时又恢复了活力。

所以我建议设置一个间隔,每隔一段时间取消一次呼叫并重新启动它。这可能有助于它在手机睡眠中存活下来。

大概是这样的:

var myCall = $.ajax({...});

Window.setInterval (refreshCall(), 10000);

function refreshCall (){
    myCall.abort ();
    myCall = $.ajax({...});
}

【讨论】:

    【解决方案2】:

    我不确定这是否可行,我现在无法测试但试一试

    $(window).focus(function() {
        updater();
    });
    

    【讨论】:

    • 在浏览器按预期工作并保持请求打开的情况下,这不会发出另一个请求吗?
    • @Katana314 这只会在用户在其他选项卡上时触发(我想这也适用于在移动设备上不活动)并聚焦我的选项卡。当然,您也可以使用某种标志来查看更新程序是否按预期工作
    • 遗憾的是这不起作用。它试过了。 $(window).focus() 不会在手机从睡眠中唤醒时调用该函数。它似乎只在您在 chrome 中的选项卡之间切换时调用该函数。
    • @Almis 谢谢,非常感谢您的努力。几天来我一直在尝试,这是一个新想法。
    • @James 我无法重现您的问题,我在我的服务器上设置了演示应用程序,它在给出响应之前延迟了 5 秒,然后我最小化了浏览器,让手机进入睡眠状态并回到我的浏览器它仍在工作......在 chrome 47 上测试
    【解决方案3】:

    像这样的高级观察者函数怎么样:

    var restartTimer = null;
    function updater(){
        $.ajax({
            type: "POST",
            url: "/listen",
            data: version,
            success: function (data) {
                version = handleUpdates(data);
                clearTimeout(restartTimer);
                updater();
            },
            error: function () {
                clearTimeout(restartTimer);
                setTimeout(updater, 1000);
            }
        });
    }
    //  Kick it when the phone wakes up.
    $(window).focus(function(){
        restartTimer = setTimeout(function(){
            initializeAll();
        }, 6000);
        updater();
    });
    

    您知道 $(window).focus 将在手机唤醒时触发,因此您尝试按照 Almis 的建议尝试 updater(),但要使用故障安全计时器。如果更新程序触发(在笔记本电脑或 iOS 上),计时器被取消并且一切正常,但如果更新程序停止,故障安全计时器会在 6 秒内触发并通过调用 initializeAll() 重新启动整个应用程序。

    【讨论】:

      【解决方案4】:

      setInterval 怎么样,它存储它被调用的时间,然后将上次调用它的时间与当前时间进行比较 - 如果你的时间间隔是 10 秒并且自上次运行以来经过的时间是 5 分钟,你可以假设你刚刚从睡梦中醒来?然后中止当前的 ajax 调用,然后重新启动它。

      【讨论】:

        【解决方案5】:

        最好的答案是“不要那样做”。您让服务器在跟踪服务器端的更改时等待响应。只需让服务器响应并让 jQuery ping 一段时间。如果您想在没有状态更改时阻止实际刷新,您可以包含 lastchanged 或 haschanged,但如果服务器正在以任何方式执行相同的工作,只需让它响应并等待下一次轮询。

        setInterval(function () { 
            $.post({"/listen", version, function (data) {
                if(data.haschanged)
                    version = handleUpdates(data);
            }).fail(function () {
                // any error correction on failed call
            });
        }, 1000);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-01
          相关资源
          最近更新 更多