2010-12-16 3 views
5

クライアントにデータを「プッシュ」するためにロングポーリングを行いたいのですが、ロングポーリングと並行して他の無関係なAJAXコールをサーバーに送信します。長いポーリングが応答を受信するまで(応答またはタイムアウトから)、私の他のAJAX呼び出しは完了しないようです。 Javascriptを実行すると、2番目の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

セッションファイルロックを経験したように思えます。

ajaxエンドポイントの先頭にあるセッションを閉じるためにsession_write_close()(またはcakephpの対応する機能)を実行します。

+0

のユーザーsession_write_close();はそれについてクールなもの – RageZ

+1

@RageZを知りませんでした:すべてのPHP開発者が – zerkms

+0

メイクセンス:-)この問題をキャッチしなければならない今、私はそれ勤務 – RageZ

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()を作ることはできますが、変更は2ページが読み込ま間のセッションでは必要ないことを確認する必要があります。

同様の質問:Simultaneous Requests to PHP Script

0

それはにsymfony 1.4のために動作します。代わりに$this->getUser()->shutdown();