ajax长轮询在页面刷新时崩溃\链接到另一个页面

我已经在这里发布了一个类似的问题,但未能得到一个可以解决我的问题的回复,问题也发生了一些变化,所以我重新发帖并迫切希望得到一些帮助!

链接到上一个问题:

用mysql进行ajax长轮询

当前代码:

JS(我从php运行它):

$oldIDq = mysql_query("SELECT * FROM messages ORDER BY id DESC LIMIT 1"); while($oldrow = mysql_fetch_array($oldIDq)){ $oldID = $oldrow['id']; } $func = ' var oldID = '.$oldID.'; function wait() { $.ajax({ type: "GET", url: "../scripts/msg_scripts/msg.php?oldid=" + oldID, async: true, cache: false, success: function (data){ if(data != \'1\'){ var json = eval(\'(\' + data + \')\'); if (json[\'msg_content\'] != "") { alert("new meassage added"); } oldID = json[\'oldID\']; setTimeout(\'wait()\',1000); } }, disconnect: function() { return false; setTimeout(\'wait()\',1000); }, error: function(XMLHttpRequest, textStatus, errorThrown){ alert("error: " + textStatus + "(" + errorThrown + ")"); setTimeout(\'wait()\',1000); } }); } $(document).ready(function(){ wait(); }); '; 

服务器:

  $connect = mysql_connect ("localhost", "root", "") or die ("couldnt connect"); mysql_select_db ("***") or die ("not found"); //if db was not found die mysql_query("SET NAMES 'utf8'"); $oldID = $_GET['oldid']; if($oldID == "") { die('timeout'); } else{ $result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1"); while($row = mysql_fetch_array($result)) { $last_msg_id = $row['id']; } while($last_msg_id <= $oldID) { usleep(10000); clearstatcache(); $result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1"); while($row = mysql_fetch_array($result)) { $last_msg_id = $row['id']; } } $response = array(); $response['msg_content'] = 'new'; $response['oldID'] = $last_msg_id; echo json_encode($response); } 

现在,我有一个在进程的服务器端运行的会话,我暂时将其删除,因为我知道长轮询有会话问题我也在页面上运行会话,发送ajax请求,因为我删除了会话我的问题在某种程度上有所改善,现在发生的事情是我基本上可以点击我网站上的链接并退出页面并收到错误,但如果我这样做超过4-5次,则浏览器会冻结每次点击在任何链接上只重新运行ajax函数,我得到一个不同的错误。 如果我刷新请求的页面,我意外得到第二个错误,浏览器冻结。 如果这是有用的信息,如果我关闭浏览器并尝试重新打开我的网站的任何页面,它根本不加载除非我重新运行我的服务器(现在在localhost上工作)也尝试使用chrome和ff。

有人可以指点我解决方案吗?

– 再次更新以检索所有新消息

阅读你的代码,你只希望返回最后一条消息,如果是这样的话,那么while循环在这种情况下是无用的。 请记住,oldID和您跳过的数据库中插入的最后一个ID之间可能会有更多“新”消息,我提供的代码也是如此

 $connect = mysql_connect ("localhost", "root", "") or die ("couldnt connect"); mysql_select_db ("***") or die ("not found"); //if db was not found die mysql_query("SET NAMES 'utf8'"); $oldID = trim($_GET['oldid']); // empty response, you may fill it with a default msg $response = array( 'msg_content' => 'none', 'oldID' => $oldID ); // this if statement will prevent to return a valid // JSON string to the ajax request if(empty($oldID)) { die('timeout'); } else { $result = mysql_query("SELECT id FROM messages WHERE id > ".addslashes($oldID)." ORDER BY id DESC"); $index = 1; // check if results have new messages if(($num_rows = mysql_num_rows($result) > 0) { $response['msg_content'] = 'new'; while($row = mysql_fetch_array($result)) { $response['new_msgs'][] = $row['id'] if($index == $num_rows) $response['oldID'] = $row['id']; // set oldID to last record } } echo json_encode($response); 

关于如何正确使用session_write_close的评论。

 session_start(); $var_id = $_SESSION['id']; $var_fn = $_SESSION['firstname']; $var_ln = $_SESSION['lastname']; $var_mail = $_SESSION['email']; // close write to session here to release it for other sources session_write_close(); if (!loggedin()){ header ("Location: index.php");} if ($_GET['id']) { $id = mysql_real_escape_string($_GET['id']);} // you are using session here, use the localized $var_id else if (isset($var_id)) { $id = mysql_real_escape_string($var_id); } 

当调用session_start()时,该点的会话被锁定以写入任何其他源,除了它所在的当前作用域(.php文件)。这是为了确保在读出期间不能更改任何值。会话值。

从文档中

会话数据通常在脚本终止后存储而不需要调用session_write_close(),但是由于会话数据被锁定以防止并发写入,因此任何时候只有一个脚本可以在会话上运行。 将框架集与会话一起使用时,由于此锁定,您将体验到逐个加载的框架。 只要对会话变量进行了所有更改,就可以通过结束会话来减少加载所有帧所需的时间。

对于卡住的问题,我认为while循环是无穷无尽的,请从浏览器http://example.com/pathto/scripts/msg_scripts/msg.php请求页面,看看会发生什么

 $counter = 0; while($last_msg_id <= $oldID) { usleep(10); // changing to be a bit faster clearstatcache(); $result = mysql_query("SELECT id FROM messages ORDER BY id DESC LIMIT 1"); $row = mysql_fetch_array($result); $last_msg_id = $row['id']; $counter++; if($counter > 100) break; } echo "counted: {$counter}"; exit();