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?以及......为什么循环应该退出?在您的 success
和 error
代码路径中,您在每次迭代时无条件地重新安排 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 进行长轮询