2010-12-16 24 views
5

Estoy buscando hacer un sondeo largo para "enviar" algunos datos al cliente y también estoy realizando otras llamadas AJAX al servidor en paralelo con el sondeo largo. Parece que mis otras llamadas AJAX no se completarán hasta que la encuesta larga haya recibido una respuesta (ya sea por respuesta o tiempo de espera). Cuando paso por el Javascript, parece que la segunda solicitud de AJAX se envía en el momento adecuado, pero la respuesta no se recibe hasta que la solicitud de encuesta larga obtiene una respuesta. ¿Alguna idea de lo que está pasando?Encuesta larga bloqueando otras llamadas AJAX

Este es el código para la porción de votación larga:

lado del servidor:

function getPlaylistTracksIfChanged($playlist_id, $numClientTracks) { 
    $reportChange = false; 
    for($i = 0; $i < 10; $i++) { 
    $numServerTracks = $this->PlaylistTrack->find('count', array(
    'conditions' => array('playlist_id' => $playlist_id) 
    ) 
    ); 

    if($numClientTracks != $numServerTracks) { 
    $reportChange = true; 
    break; 

    } 

    sleep(3); 

    } 

    if($reportChange) { 
    $playlist_tracks = $this->PlaylistTrack->find('all', array(
    'conditions' => array('playlist_id' => $playlist_id), 
    'order' => array('PlaylistTrack.position') 
    ) 
    ); 

    $this->set('playlist_tracks', $playlist_tracks); 
    $this->layout = false; 
    $this->render('show_playlist_tracks_list'); 

    } else { 
    $this->autoRender = false; 
    return 'false'; 
    } 

} 

lado del cliente:

function checkForChangesOnServer() { 
$.post('/getResultsIfChanged/' + playlist_id + '/' + $('#sortable_tracks').children().size(), function(results) { 

    if(results == 'false') { 
    //alert('no change'); 
    } else { 
    //alert('change'); 
    } 

    checkForPlaylistChangesOnServer(); 

}); 
} 

Y una muestra de otra llamada AJAX:

Lado del servidor:

function getLibraryTracksStartingWithLetter($user_id, $letter) { 
    $results = $this->Track->find(
    'all', 
    array(
    'conditions' => array(
    'user_id' => $user_id, 
    'OR' => array(
     'Track.artist LIKE' => $letter . '%', 
     'Track.name LIKE' => $letter . '%' 
    ) 
    ), 
    'order' => array('case when Track.artist = "" then 1 else 0 end', 'Track.artist', 'Track.name') 
    ) 
); 

    $this->set('results', $results); 
    $this->layout = false; 
    $this->render('show_library_results_list'); 
} 

lado del cliente:

function loadLibraryResultsForLetter(letter) { 
highlightLetterFilter(letter); 

$.post('/getLibraryTracksStartingWithLetter/' + user_id + '/' + letter, function(results) { 
    updateLibraryResults(results); 
}); 
} 

Respuesta

13

Parece que ha experimentado el bloqueo de archivo de sesión.

Realice session_write_close() (o la función correspondiente en cakephp) para cerrar la sesión en el comienzo del punto final ajax.

+0

no sabía nada de las cosas que se enfríe – RageZ

+1

@RageZ: todos los desarrolladores de PHP debe coger este problema :-) – zerkms

+0

tiene sentido ahora estoy pensando en ello – RageZ

0

Esto ocurre debido a los bloqueos de archivos de sesión. En CakePHP puede elegir otras opciones para la administración de la sesión. Puede guardar sesiones en la base de datos, en el caché, etc. Por lo tanto, no espera a problemas de bloqueo de archivos.

Las configuraciones incorporadas son:

php - Guarda sesiones con los ajustes estándar en su archivo php.ini.

cake - Guarda las sesiones como archivos dentro de la aplicación/tmp/sessions. Esta es una buena opción cuando está en hosts que no le permiten escribir fuera de su propio directorio de inicio .

base de datos: utilice las sesiones de base de datos incorporadas.

caché: utiliza las sesiones de caché integradas.

http://book.cakephp.org/2.0/en/development/sessions.html#built-in-session-handlers-configuration

Por supuesto se puede hacer session_write_close(), pero usted debe estar seguro de que no hay cambios necesarios en la sesión entre dos cargas de la página.

Pregunta similar: Simultaneous Requests to PHP Script

0

funciona para Symfony 1.4. session_write_close(); de usuario en lugar de $this->getUser()->shutdown();

Cuestiones relacionadas