2013-08-30 2 views
0

Я пытаюсь создать многопользовательскую чат-систему, в которой данные сохраняются в базе данных и извлекаются по запросу. Следующий фрагмент кода - всего лишь пример, и я знаю, что в нем есть много хороших SQL-инъекций, которые я изменю, когда все это будет хорошо работать. Плюс, сохраняя код сервера php в том же файле, просто сохранить код в одном месте, проблема, которую я объясню здесь, все еще существует, когда код сервера находится в другом php-файле.Длинный опрос дает ошибку базы данных

Код работает хорошо, но проблема в том, что моя база данных перестает отвечать на некоторое время через некоторое время. Если больше пользователей одновременно общаются (несколько экземпляров этого скрипта), база данных перестает отвечать на них в течение некоторого времени очень скоро, и она начинает отвечать через некоторое время снова. Просьба указать, где я ошибаюсь.

<?php 
    if($_POST){ 
     $db=mysqli_connect("localhost","***","****","****"); 
     if (isset($_POST['update'])){ 
      $q = 0; 
      $lasttime = isset($_POST['timestamp']) ? $_POST['timestamp'] : 0; 
      while (1){ 
       sleep(3); 
       $mresult = mysqli_query($db,"SELECT * FROM tblchat WHERE msg_datetime > $lasttime"); 
       $wresult = mysqli_query($db,"SELECT writer_alias FROM tblwriter WHERE writer_isactive=1 AND  (UNIX_TIMESTAMP(NOW())-last_activity)<10"); 
       if (mysqli_num_rows($mresult)){ $msgs = array(); while ($row = mysqli_fetch_object($mresult)) { $msgs[] = $row; }  mysqli_free_result($mresult); echo json_encode(array("writers"=>$writers,"msgs"=>$msgs)); flush(); break; } 
       if (mysqli_num_rows($wresult)){ $writers = array(); while ($row = mysqli_fetch_object($wresult)) { $writers[] = $row; } mysqli_free_result($wresult); echo json_encode(array("writers"=>$writers,"msgs"=>$msgs)); flush(); break; } 
       ++$q; 
       if ($q>15){ break; } 
      } 
     }elseif (isset($_POST['save'])){ 
      $msg = isset($_POST['msg']) ? $_POST['msg'] : ''; 
      if ($msg != ''){ 
       $from = $_POST["from"]; 
       $to = $_POST["to"]; 
       mysqli_query($db,"INSERT INTO tblchat VALUES('".$to."','".$from."','".$msg."','".time()."')"); 
       echo json_encode(array("success"=>"1")); 
       flush(); 
      } 
     } 
     mysqli_close($db); 
     exit(); 
    } 
?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>testing comet</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
    </head> 
    <body> 
<p> 
    <input type="text" name="word" id="word" value="" /> 
    <input type="button" name="send" value="Send" id="mybutton"/> 
</p> 
<div id="content"></div> 

<script type="text/javascript"> 
var lastime = 0; 
$("#mybutton").click(function(){ 
    $.post(location.href, {save:"1",from:"1",to:"5",msg:$("#word").val()}, function(data){ 
     console.log(data); 
     $("#word").val(""); 
    }, "json"); 
}); 

$(document).ready(function(){ update(); }); 

function update(){ 
    console.log("update called"); 
    $.ajax({ type: "POST", url: location.href, data: {update:"1",timestamp:lastime}, success: function(data1){ 
     console.log(data1); 
     lastime = handleDATA(data1.msgs); 
    }, dataType: "json", complete: update, timeout: 60000 }); 
} 

function handleDATA (data){ 
    for(i=0;i<data.length;i++){ 
     $("#content").append(data[i].msg_from +": "+ data[i].msg+"</br>"); 
    } 
    return data[data.length-1].msg_datetime; 
} 
</script> 

</body> 
</html> 
+0

Вы проверили, что произойдет, если '$ mresult' и' $ wresult' по какой-то причине вернутся к false (или 0 строк)? Это может создать бесконечный цикл. – Jason

+0

Итак, скрипт будет работать, даже если время ожидания ajax-запроса? Если это так, можете ли вы предложить способ добровольного разрыва цикла после 30 секунд.? –

+0

отредактировал код и добавил безопасную проверку, после 15 попыток код сломает цикл и выйдет. любезно скажите мне, если его безопасная проверка. –

ответ

0

Хотя это может или не может быть абсолютным решения, давайте исправить некоторые вещи с вашим кодом (а также некоторое форматирование, чтобы проиллюстрировать лучше):

Старого раздел (строки 7 - 15):

while (1){ 
    sleep(3); 
    $mresult = mysqli_query($db,"SELECT * FROM tblchat WHERE msg_datetime > $lasttime"); 
    $wresult = mysqli_query($db,"SELECT writer_alias FROM tblwriter WHERE writer_isactive=1 AND  (UNIX_TIMESTAMP(NOW())-last_activity)<10"); 
    if (mysqli_num_rows($mresult)){ $msgs = array(); while ($row = mysqli_fetch_object($mresult)) { $msgs[] = $row; }  mysqli_free_result($mresult); echo json_encode(array("writers"=>$writers,"msgs"=>$msgs)); flush(); break; } 
    if (mysqli_num_rows($wresult)){ $writers = array(); while ($row = mysqli_fetch_object($wresult)) { $writers[] = $row; } mysqli_free_result($wresult); echo json_encode(array("writers"=>$writers,"msgs"=>$msgs)); flush(); break; } 
    ++$q; 
    if ($q>15){ break; } 
} 

Новая функция в Top:

// This is separate of the while below, put this 
// function at top of your script (less code later) 

function toArray(myqli_result $result) 
{ 
    while($row = mysqli_fetch_object($result)) 
    { 
     $array[] = $row; 
    } 
    mysqli_free_result($result); 

    return $array; 
} 

Новое Хотя заявление:

//Replacement While Function 
while($q < 15) 
{ 
    sleep(3); 

    $mresult = mysqli_query($db, "SELECT * FROM tblchat WHERE msg_datetime > $lasttime"); 
    $wresult = mysqli_query($db, "SELECT writer_alias FROM tblwriter WHERE writer_isactive = 1 AND (UNIX_TIMESTAMP(NOW()) - last_activity) < 10"); 

    //If you need both results, you must check for both results 
    //And do what you need to do, BEFORE break; 
    if (mysqli_num_rows($mresult) > 0 && mysqli_num_rows($wresult) > 0) 
    { 
     $msgs = toArray($mresult); 
     $writers = toArray($wresult); 

     echo json_encode(array("writers" => $writers, "msgs" => $msgs)); 

     flush(); 
     break; 
    } 
    ++$q; 
} 

Чистый код делает счастливых программистов, а также значительно облегчает отладку позже.

Если вам нужны оба набора результатов (как вам кажется, вы делаете), вы не получите их обоих по мере того, как ваш код будет сейчас, вы вырветесь из него, когда вы получите свой первый результат. Это позволит обрабатывать оба запроса до json_encode.

Здесь toArray(mysqli_result $result) - это функция, которая принимает объект mysqli_result и генерирует его и возвращает массив, освобождая результат.

Если вы обнаружите, что несколько раз повторяете одни и те же строки кода с разными переменными, вы можете создать вместо него функцию.

+0

Большое спасибо Джейсону. Очень ценю. –

Смежные вопросы