2010-12-16 134 views
5

我正在尋找做長輪詢來「推」一些數據下來到客戶端,我也做了與長輪詢並行服務器的其他無關的AJAX調用。看起來,我的其他AJAX調用不會完成,直到長時間輪詢收到響應(無論是響應還是超時)。當我瀏覽Javascript時,看起來第二個AJAX請求在適當的時候被髮送,但是在長的輪詢請求得到響應之前沒有收到響應。任何想法是怎麼回事?長輪詢鎖定其他AJAX呼叫

這裏是長輪詢部的代碼:

服務器端:

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

} 

客戶端:

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

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

    checkForPlaylistChangesOnServer(); 

}); 
} 

而另一AJAX調用的示例:

服務器端:

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

客戶端:

function loadLibraryResultsForLetter(letter) { 
highlightLetterFilter(letter); 

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

回答

13

好像你所經歷的會議文件鎖定。

執行session_write_close()(或cakephp中的相應函數)在ajax端點開始時關閉會話。

+0

用戶session_write_close();不知道它很酷的東西 – RageZ 2010-12-16 03:33:01

+1

@RageZ:每一個PHP開發人員應該抓住這個問題:-) – zerkms 2010-12-16 03:34:07

+0

有意義現在我想它 – RageZ 2010-12-16 03:34:43

0

發生這種情況是因爲會話文件鎖定。在CakePHP中,您可以選擇其他用於會話管理的選項。您可以將會話保存在數據庫中,緩存等中。因此,您不必等待文件鎖定問題。

內置的配置是:

PHP - 保存會話在php.ini文件的標準設置。

蛋糕 - 將會話保存爲app/tmp/sessions中的文件。如果主機不允許您在自己的 主目錄之外寫入,則這是一個很好的 選項。

數據庫 - 使用內置的數據庫會話。

緩存 - 使用內置的緩存會話。

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

當然你也可以讓session_write_close(),但你應該確保需要會話沒有改變兩頁的負荷之間。

類似的問題:Simultaneous Requests to PHP Script

0

它爲symfony的1.4。而不是$this->getUser()->shutdown();