【问题标题】:From polling to long polling从轮询到长轮询
【发布时间】:2019-05-28 04:59:54
【问题描述】:

所以我有一个脚本,它使用基本轮询来实时显示数据库中的记录总数

所以没有什么复杂的,所以任何人都可以给我一个长轮询结构中的代码示例。我之所以问这个问题是因为google上的所有文章

search 为我提供了 jQuery 中的示例我似乎无法找到在我的情况下有意义的纯 JavaScript 示例。这是一个 .gif 截图 我的代码在行动,所以你们知道我的意思。

这是我需要转换或更改为长轮询的基本轮询示例代码。

index.php

<style>
    #label{
    margin: 0;
    color: red;
    font-weight: bold;
    }
    </style>

    <script>
    document.addEventListener('DOMContentLoaded',function(){

    /**********************************************************************
    Check for a new record amount in the data base
    **********************************************************************/

    function checkForNewRecords(){

    var xhr= new XMLHttpRequest();

    xhr.onreadystatechange= function(){

        if(xhr.readyState == 4){
        document.querySelector('#output').innerHTML= xhr.responseText;

        }
      }

    xhr.open('POST','check-for-new-records.php');
    xhr.send();  

    }

    setInterval(function(){checkForNewRecords()},1000);

    });
    </script>

    <p id='label'>Total records in the database in real time in basic polling</p>

    <div id='output'></div>

check-for-new-records.php

<?php

    $db_servername= 'localhost';
    $db_username='jd';
    $db_password= '1234';
    $db_name= 'test';

    $db_connect= new mysqli($db_servername,$db_username,$db_password,$db_name);

    $db_query= "SELECT COUNT(id) AS id FROM example";

    $db_result= $db_connect->query($db_query);
    $db_row= $db_result->fetch_object();

    $total_records= $db_row->id;

    ?>

    <style>
    #total-records{
    margin-top: 0;
    }
    </style>

    <p id='total-records'><?php echo $total_records; ?></p>

那么你们如何将其转换为长轮询,请不要建议其他方法或不提供没有帮助的答案我只对我所要求的内容感兴趣,我很确定其他人也对纯 JavaScript 版本感兴趣,我之所以这么说是因为我

已经在网上询问这个话题很长时间了,似乎没有人有兴趣回答这个问题,或者他们认为回答这个问题太难了,为什么有这么多关于这个话题的 jQuery 示例,而不是基于纯 JavaScript 而不是每个人都喜欢使用图书馆。我只是说我对从这个基于纯 JavaScript 的主题中得到的无用答案感到不满意,只是提醒一下。

【问题讨论】:

  • fwiw,你最后的句子很可能会被否决。只是提醒一下。
  • 希望有帮助,我不想编写解决方案,因为现在是 12 月 31 日,但这里的解释很清楚 developer.hyvor.com/php/ajax-long-polling
  • 你永远不应该使用setInterval,而是使用setTimeout。如果您使用setTimeout,则轮询和长轮询仅在延迟发生的地方有所不同。对于轮询,服务器将立即响应(即使没有发生更改),客户端将等待 n 秒以发送下一个请求。对于长轮询,服务器将等待响应,直到有新数据可用(或发生超时),客户端收到响应后将立即发送新请求。
  • 感谢大家的回复,但是为什么这个问题对大多数人来说如此复杂,但是如果有人问这个问题如何在 jQuery 中完成,那么快速给出的答案是 JavaScript 对大多数人来说很复杂现在天?我只是不明白,抱歉,我对缺乏关于使用纯 JavaScript 执行此操作的信息感到沮丧,我只是说,感谢 Polack 的链接,但我已经尝试了该链接,但我无法得到它与我的例子一起工作,我从我的例子中学到了最好的东西,但是如果你们不知道怎么回事,我只能继续在线询问,因为我失败了很多。
  • 问几乎相同的问题Converting this from basic polling to long polling 却不说明这些答案中缺少什么,这是一种非常糟糕的方式。

标签: javascript ajax long-polling


【解决方案1】:

您永远不应该使用setInterval,而是使用setTimeout

如果您使用setTimeout,那么轮询和长轮询的基本区别仅在于延迟发生的地方。对于轮询,服务器将立即响应(即使没有发生更改),客户端将等待 n 秒以发送下一个请求。对于长轮询,服务器将等待响应,直到有新数据可用(或发生超时),客户端收到响应后将立即发送新请求。

XMLHttpRequestfetchjQuery实现完全没有区别,唯一不同的客户端是下一个请求的延迟。

投票:

function checkForNewRecords() {

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function() {

    if (xhr.readyState == 4) {
      document.querySelector('#output').innerHTML = xhr.responseText;

      setTimeout(checkForNewRecords, 1000); // polling has the delay on the client
    }
  }

  xhr.open('POST', 'check-for-new-records.php');
  xhr.send();

}

checkForNewRecords()

长轮询:

function checkForNewRecords() {

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function() {

    if (xhr.readyState == 4) {
      document.querySelector('#output').innerHTML = xhr.responseText;

      setTimeout(checkForNewRecords, 0);
      // long-polling has the delay on the server 
      // the client initiates a new request immediatly after receiving the response.
    }
  }

  xhr.open('POST', 'check-for-new-records.php');
  xhr.send();

}

checkForNewRecords()

另一方面,在服务器端,您通常必须更改一些内容才能使长轮询有效地工作。

针对优化的轮询和长轮询之间的重要区别在于如何告诉服务器何时发送更新信息,但这完全独立于您用于请求数据的方法。

【讨论】:

  • 感谢您的回复 t.niese,但我认为您的基本投票与您提供的长投票示例之间没有区别。我所看到的只是向我回答您的其他 cmets 的时间不同了有用的答案然后我试图关闭该帖子但它没有让我但是如果你不知道如何在服务器端执行此操作也可以如果你不知道我很高兴有人到达很好,我希望我能解决这个问题
  • @fsofb 这就是我在答案中所说的。这是因为在客户端的长轮询和轮询之间没有其他区别。轮询意味着,服务器不支持延迟(保持响应直到有更新),因此客户端负责延迟下一个请求以减少网络负载的任务。对于长轮询,服务器能够延迟响应,直到有新的/更新的数据可用,因此服务器负责延迟响应并控制网络负载。因此,在客户端,差异实际上只是超时值。
  • @fsofb 要明确在长轮询中有两个部分,您的问题是关于客户端部分如何使用 JavaScript 而不是使用 jQuery。这就是我回答的问题,这与您使用 jQuery 执行此操作的方式没有什么不同。服务器端部分是一个不同的主题,与请求端使用的语言和/或库完全无关。因此,如果您想知道如何执行服务器端部分,则需要询问。
猜你喜欢
  • 2013-08-08
  • 2011-04-20
  • 1970-01-01
  • 2020-04-26
  • 2012-02-24
  • 2015-01-23
  • 1970-01-01
  • 2014-08-10
  • 2012-08-16
相关资源
最近更新 更多