0

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

链接到上一个问题:

使用 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 函数,我得到一个不同的错误。如果我刷新请求的页面,我会立即收到第二个错误并且浏览器冻结。如果这是有用的信息,如果我关闭浏览器并尝试重新打开我网站的任何页面,除非我重新运行我的服务器(现在在本地主机上工作),否则它根本不会加载,也用 chrome 和 ff 尝试过。

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

4

1 回答 1

1

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

阅读您的代码,您只希望返回最后一条消息,如果是这样,那么在这种情况下,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();
于 2012-09-12T16:04:50.393 回答