页面刷新\链接到另一页面时,ajax长轮询崩溃 [英] ajax long polling crashes at page refresh\links to another page

查看:96
本文介绍了页面刷新\链接到另一页面时,ajax长轮询崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在这里发布了类似的问题,但是未能获得能够解决我的问题的答复,问题也有所改变,因此我重新发布并渴望获得帮助!

i have already posted a similar question here, but failed to get a response that will fix my problem, also the problem has changed a bit so i'm re-posting and desperate to get some help!

链接到上一个问题:

使用mysql进行ajax长轮询

当前代码:

JS(我从php运行它):

JS(I run it from 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上运行),否则它根本不会加载.

now, i had a session running on the server side of the process and i removed it for now because i understood that long polling has a problem with sessions i also have sessions running on the page which sends the ajax request, since i removed the session my problem has improved in a way, what happens now is that i can basically click on a link on my website and exit the page and get an error, but if i do it more than 4-5 times, the browser freezes an every click on any link just reruns the ajax function and i get a different error. if i refresh the page of the request i imidetly get the second error and the browser freezes. also if that's helpful information if i close the browser and try to reopen any page of my site it doesn't load at all unless i rerun my server(working on localhost right now) also tried it with chrome and ff.

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

can some one please point me towards the solution?

推荐答案

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

-- Updated again to retrieve all new messages

阅读代码,您只希望返回最后一条消息,如果是这样,则while循环在这种情况下几乎没有用.请记住,在oldID和您跳过的数据库中插入的最后一个ID之间可能会有更多的新"消息,因此我提供的代码

Reading your code, you only wish to return the last message, if so then the while loops are in this case pretty useless. Do keep in mind that there might be more 'new' messages between the oldID and the last ID inserted into your database which you skip, so does this code I provide

$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 的评论.

To your comment on how to use session_write_close properly.

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文件除外).这是为了确保在执行过程中不能更改任何值.会话值的读取.

When session_start() is called, the session at that point is locked for writing to any other source, except the current scope (.php file of execution) it's in. This is to make sure that no values can be changed during the readout of session values.

文档

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

Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.

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

To the getting stuck problem, I think the while loop is endless, request the page from your browser http://example.com/pathto/scripts/msg_scripts/msg.php and see what happens

$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();

这篇关于页面刷新\链接到另一页面时,ajax长轮询崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆