2014-01-20 2 views
1

Я внедрил длинный опрос механизм с использованием XMLHttprequest. Моя проблема заключается в том, что после закрытия браузера процесс на стороне сервера продолжает работать и не завершается.XmlHttpRequest не завершает обработку запроса

Веб-сервер HTTPD Apache и процесс является PHP скрипт.

Я хочу, чтобы скрипт php закрывался после закрытия браузера.

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

сценарий клиентской стороны, использует onreadystatechange, чтобы попытаться прочитать частичные данные, не требуя нового XMLHttprequest для каждого сообщения. некоторые браузеры не позволяют читать частичные данные, пока весь ответ не закончил:

<!DOCTYPE html> 
<html> 
<head> 
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"></meta> 
<script type="text/javascript" src="jquery.min.js"></script> 
<script type="text/javascript"> 
    $(document).ready(NewReq); 

    var mode = 0; 
    function NewReq() { 
    var Req = new XMLHttpRequest(); 
    var url = 'a.php'; 
    if (mode) { 
     url += '?mode=' + mode; 
    } 
    Req.open('GET', url); 
    Req.onreadystatechange = function(event) { 
     var handler = ReadyState[this.readyState]; 
     if (typeof handler == 'function') { 
     handler(this); 
     } 
    }; 
    inc_mycookie(); 
    Req.send(); 
    } 

    var ReadyState = [ 
    //'NotInit', 'ReqRec', 'ConEst' 
    null , null, null, 
    partial // 'Proccessing' 
    , 
    complete //'Finishied' 
    ]; 

    function partial(Req) { //'Proc' 
    if (mode == 1) { 
     return; 
    } 
    try { 
     var strings = Req.response.split(';'); 
     strings.pop(); 
     var data = JSON.parse(strings.pop()); 
     $('#message').text(data); 
     mode = 2; 
    } 
    catch (e) { 
     $('#message').text(e.message); 
     mode = 1; 
    } 
    return; 
    } 

    function complete(Req) { 
    var last = $('#message').text(); 
    $('#output').text(last); 
    NewReq(); 
    } 

    function inc_mycookie() { 
    var matches = document.cookie.match(/(?:^|;)mine=([^;]+);?/); 
    if (matches) { 
     var inc = parseInt(matches[1]) + 1; 
     document.cookie = 'mine=' + inc; 
    } 
    } 

</script> 
</head> 
<body> 
<h3> output </h3> 
<div id="output"></div> 
<h3> partial </h3> 
<div id="message"></div> 
</body> 
</html> 

и вот скрипт PHP (Апач «php_value output_buffering Off»):

<?php 
    header('Content-type: application/json'); 
    if (!isset($_COOKIE['mine'])) { 
    setcookie('mine', 23); 
    $_COOKIE['mine'] = 23; 
    } 
    $mode = isset($_GET['mode']) ? $_GET['mode'] : 1; 
    print json_encode('test_' . $_COOKIE['mine']) . ';'; 
    if ($mode == 2) { 
    $iter = 8; 
    while($iter) { 
     sleep(2); 
     $iter--; 
     error_log('a.php:' . $iter); 
     // if i remove this line, then erro_log will continue to show even when browser is closed 
     print json_encode('test_' . $_COOKIE['mine'] . '_' . $iter) . ';'; 
    } 
    } 
?> 

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

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

+0

Что такое код у вас есть до сих пор? – everton

+0

Я добавил код и обнаружил, что php должен попытаться вывести данные обратно клиенту, чтобы обнаружить, что соединение было прервано –

+0

Я завершил окончательное описание проблемы –

ответ

0

один из возможных решений является добавление интервал:

<?php 
$iter = 200; 
while($iter) { 
    sleep(2); 
    $iter--; 
    error_log('a.php:' . $iter); 
    if (update_exist()) { 
    print json_encode('test_' . $_COOKIE['mine'] . '_' . $iter) . ';'; 
    } 
    else if (($iter-200)%20 == 0) { // 180, 160, 140 ... 40, 20, 0 
    print json_encode('check connection : ' . $iter) . ';'; 
    } 
} 
Смежные вопросы