PHP + jQuery - 数据库数据的长轮询不起作用(它不会破坏循环)


PHP + jQuery - Long Polling with database data aren't working (it doesn't break the loop)

我正在尝试在我的内部网络上实现一个长轮询系统,大多数用户使用 IE,有些用户也使用移动设备,这就是为什么我尝试使用长轮询而不是 websocket 来做到这一点。

我按照这个视频 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);
?>

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

我做错了什么吗?

谢谢

我最终找到了解决方案。

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

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

天哪,我怎么会忘记这一点。

谢谢大家。

尝试在

while 循环中用$currentmodif = $dados['HORA']);替换$currentmodif = $dados['DATAHORA']);

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

更改$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);
?>

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

在用MySQL重写代码并挠头为什么它似乎工作正常之后,我发现了问题:

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

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

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);
        }
      })
}