PHP + jQuery - 使用数据库数据进行长轮询不起作用(它不会打破循环)

Posted

技术标签:

【中文标题】PHP + jQuery - 使用数据库数据进行长轮询不起作用(它不会打破循环)【英文标题】:PHP + jQuery - Long Polling with database data aren't working (it doesn't break the loop) 【发布时间】:2013-09-20 18:50:33 【问题描述】:

我正在尝试在我的内部网络上实现一个长轮询系统,大多数用户使用 IE,有些用户也使用移动设备,这就是我尝试使用长轮询而不是 websockets 的原因。

我关注了这个视频http://www.screenr.com/SNH,并编辑了一些代码来处理我的数据库。 (火鸟)

看起来一切正常,但它并没有打破循环。也许这是一个孩子的错误,但我看不到,这就是为什么我需要你的帮助!

代码如下:

jQuery + Ajax:

var timestamp = null;

function waitForMsg()      
    $.ajax(
        type: "GET",
        url: "getData.php?timestamp=" + timestamp,
        async: true,
        cache: false,

        success: function(data)
            alert('It Works');
            var json = eval('(' + data + ')');
            timestamp = json['timestamp'];
            setTimeout('waitForMsg()',15000);
        ,
        error: function(XMLHttpRequest, textStatus, errorThrown)
            alert("A - " + XMLHttpRequest + " - error: " + textStatus + " (" + errorThrown + ")");
            setTimeout('waitForMsg()',15000);
        
    );


$(document).ready(function()
    waitForMsg();
);

</script>

getData.php('DATAHORA' 是时间戳字段)

<?php
    set_time_limit(0);
    @ini_set("memory_limit",'64M');

    require_once('../classes/conexao.php');

    $banco = Conexao :: getConexao();
    $sql = "SELECT FIRST 1 DATAHORA FROM AGENDAMENTOSBBM ORDER BY DATAHORA DESC";
    $res = $banco->execute($sql);
    $dados = $banco->fetch($res);
    if($dados)
        $currentmodif = $dados['DATAHORA']);
    else
        $currentmodif = 0;

    $lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;

    while( $currentmodif <= $lastmodif )
        usleep(10000);
        $sql = "SELECT FIRST 1 DATAHORA FROM AGENDAMENTOSBBM ORDER BY DATAHORA DESC";
        $res = $banco->execute($sql);
        $dados = $banco->fetch($res);
        if($dados)
            $currentmodif = $dados['DATAHORA']);
        else
            $currentmodif = 0;
    

    $response = array();
    $response['timestamp'] = $currentmodif;
    echo json_encode($response);

?>

当我插入、更新或删除一些数据时,时间戳字段会更新为当前时间戳。 我可以看到页面进入了循环,但是我不知道为什么它永远不会结束。

我做错了吗?

谢谢

【问题讨论】:

eval()?当 jquery 已经具有非常好的内置 JSON 处理功能时,为什么要评估 json?以及......为什么循环应该退出?在您的 successerror 代码路径中,您在每次迭代时无条件地重新安排 waitForMsg() - 循环无法退出。如果你想让它退出,你必须给它一些退出的方法。 @MarcB 我只是跟着视频教程,这就是为什么eval() 和其余的。如果我尝试相同的代码但使用文件和filetime,它就像一个魅力。在这段代码中,如果在数据库中添加了新信息,则应该退出循环并传递json值,然后返回带有循环的页面。 【参考方案1】:

我终于找到了解决办法。

就这么简单。我的代码没有关闭与ibase_close的连接

我所做的是在完成查询过程后将其更改为关闭。 然后在循环内,我需要重新连接服务器。

天哪,我怎么忘了。

谢谢大家。

【讨论】:

【参考方案2】:

尝试在 while 循环中将 $currentmodif = $dados['DATAHORA']); 替换为 $currentmodif = $dados['HORA']);

您要求一个不存在的数组键,该键始终为空,因此如果 $lastmodif 不为空,您的循环将永远运行。

【讨论】:

对不起,兄弟,但是根据您的回答,我看到我输入了错误的 sql 行,但还是谢谢【参考方案3】:

$currentmodif = $dados['DATAHORA']);,看:

<?php
set_time_limit(0);
@ini_set("memory_limit",'64M');

require_once('../classes/conexao.php');

$banco = Conexao :: getConexao();
$sql = "SELECT FIRST 1 DATAHORA FROM AGENDAMENTOSBBM ORDER BY DATAHORA DESC";
$res = $banco->execute($sql);
$dados = $banco->fetch($res);
if($dados)
    $currentmodif = $dados['DATAHORA']);
else
    $currentmodif = 0;

$lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;

while( $currentmodif <= $lastmodif )
    usleep(10000);
    $sql = "SELECT FIRST 1 DATA, HORA FROM AGENDAMENTOSBBM ORDER BY DATA DESC,HORA DESC";
    $res = $banco->execute($sql);
    $dados = $banco->fetch($res);
    if($dados)
        $currentmodif = $dados['DATA'].$dados['HORA']; // Before : $dados['DATAHORA']);
    else
        $currentmodif = 0;


$response = array();
$response['timestamp'] = $currentmodif;
echo json_encode($response);

?>

我不知道你的数据库设计如何,我建议你自己改变 也许你的错误就在那条线上。但我不能决定,因为我没有时间修复它,我必须做我的项目。 如果我错了,我很抱歉。祝你好运

【讨论】:

对不起,兄弟,但是根据您的回答,我看到我打错了 sql 行,但还是谢谢【参考方案4】:

mysql 中重写代码并为为什么它似乎工作正常而摸不着头脑后,我发现了问题:

您需要将初始 var timestamp 设置为 0,而不是 null。如果将其设置为 null,jQuery 会将其作为字符串“null”(?timestamp=null) 发送。在 PHP 中,它会将这个字符串 "null" 与 $currentmodif 的任何数字进行比较,所以最后你永远不会进入你的 while 循环。

【讨论】:

我已经试过了,而且总是一样。无限循环,没有任何反应:( 一旦它进入循环,你是否在表中插入一个新行,其时间戳比前一个更高?因为它似乎工作...... 在另一个页面中,我将数据插入到具有更高时间戳的表中,或者我也更新具有更高时间戳的行。在这里检查我的其他 cmets,我已经尝试过手动操作,但也没有用。 所以通过其他 cmets 和 this,您已将时间戳更改为 0,进入循环,然后手动插入时间戳,确认您获得了新的时间戳 $dados 和 $currentmodif 已更新,而你仍然陷入困境? 查询看起来不错,但我对 firebird 不熟悉。就像我说的,它适用于 MySQL;也许第一个查询的结果被缓存在某个地方?【参考方案5】:

尝试评估您的查询并查看它们返回的内容,以便您可以验证返回的数据并确保数组$dados 具有访问数组$dados 的任何数据所需的数据和键。

【讨论】:

如果我使用var_dump($dados) 之类的东西,我可以看到它返回的正是我所需要的。如果我模拟手动传递数据或使用标志来停止循环内的`while, it works, but still not does any changes on $currentmodif`【参考方案6】:
var longpollError = false;
function longPoll()
    $.ajax(
        url: "socialPolling",
        type: 'GET',
        dataType: 'json',
        data: param1: 'value1',
        timeout: 30000 // timeout every 10 sec
      ).done(function(dataJson) 

        //Success code goes here

      )
      .fail(function(data) 
         longpollError = true; //mark this to true if there is an error

      ).always(function(data) 
        if(longpollError==false) //if there is no error request it again
          setTimeout(function() 
            longPoll();
          , 3000);

        

      )

【讨论】:

以上是关于PHP + jQuery - 使用数据库数据进行长轮询不起作用(它不会打破循环)的主要内容,如果未能解决你的问题,请参考以下文章

在带有 turbolink 的 Rails 中使用 jQuery 进行长轮询

使用 php curl 进行长轮询

使用 Httpclient 进行长轮询

使用 WinAPI 的 InternetReadFile() 进行长轮询

使用 Xampp 进行长轮询

QT使用websocket进行长连接