2010-12-16 8 views
5

Ich bin auf der Suche nach langen Polling "Push" einige Daten auf den Client und ich mache auch andere unabhängige AJAX Anrufe an den Server parallel zu den langen Polling. Es scheint, dass meine anderen AJAX-Anrufe nicht abgeschlossen werden, bis die lange Umfrage eine Antwort erhalten hat (entweder von einer Antwort oder Timeout). Wenn ich durch das Javascript gehe, scheint es, dass die zweite AJAX-Anfrage zur richtigen Zeit gesendet wird, aber die Antwort wird nicht empfangen, bis die lange Abfrageanfrage eine Antwort erhält. Irgendeine Idee was ist los? HierLong Polling Sperren andere AJAX Anrufe

ist der Code für den langen Abfrageteil:

Server-Seite:

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'; 
    } 

} 

Client-Seite:

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

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

    checkForPlaylistChangesOnServer(); 

}); 
} 

und eine Probe eines anderen AJAX-Aufruf:

Serverseite:

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'); 
} 

Client-Seite:

function loadLibraryResultsForLetter(letter) { 
highlightLetterFilter(letter); 

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

Antwort

13

Scheint, wie Sie die Sitzung Dateisperre erfahren.

Führen Sie session_write_close() (oder die entsprechende Funktion in cakephp) aus, um die Sitzung zu Beginn des Ajax-Endpunkts zu schließen.

+0

wusste nicht, es cool stuff – RageZ

+1

@RageZ: jeder PHP-Entwickler dieses Problem :-) – zerkms

+0

Sinn fangen sollte jetzt wo ich darüber denke – RageZ

0

Dies geschieht aufgrund von Sitzungsdateisperren. In CakePHP können Sie andere Optionen für die Sitzungsverwaltung auswählen. Sie können Sitzungen in der Datenbank, im Cache usw. speichern. Sie warten also nicht auf Probleme mit der Dateisperre.

Die Einbau-Konfigurationen sind:

php - Speichert Sitzungen mit den Standardeinstellungen in der php.ini-Datei.

Kuchen - Speichert Sitzungen als Dateien in app/tmp/Sitzungen. Dies ist eine gute Option auf Hosts, die Ihnen nicht erlauben, außerhalb Ihres eigenen Home-Verzeichnisses zu schreiben.

Datenbank - Verwenden Sie die integrierten Datenbanksitzungen.

Cache - Verwenden Sie die integrierten Cache-Sitzungen.

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

Natürlich können Sie session_write_close() machen, aber Sie sollten sicher sein, dass keine Änderungen in der Sitzung zwischen zwei Seite geladen wird benötigt.

ähnliche Frage: Simultaneous Requests to PHP Script

0

es funktioniert für symfony 1.4. session_write_close(); Benutzer statt $this->getUser()->shutdown();