2013-07-25 5 views
7

Ich versuche Long Polling-Funktionalität in Laravel zu programmieren, aber wenn ich die Funktion sleep() verwenden, friert die gesamte Anwendung/blockiert bis zur Funktion sleep() erledigt. Weiß jemand, wie man dieses Problem löst?Lange Abfrage in Laravel (Schlaf() -Funktion machen Anwendung einfrieren)

Mein Javascript sieht wie folgt aus:

function startRefresh() { 

longpending = $.ajax({ 
    type: 'POST', 
    url: '/getNewWords', 
    data: { wordid: ""+$('.lastWordId').attr('class').split(' ')[1]+"" }, 
    async: true, 
    cache: false 
}).done(function(data) { 
    $("#words").prepend(data); 
    startRefresh(); 
}); 

} 

Und die PHP:

public function longPolling() 
{ 
    $time = time(); 
    $wordid = Input::get('wordid'); 
    session_write_close(); 
    //set_time_limit(0); 

    while((time() - $time) < 15) { 
     $words = Word::take(100)->where('id', '>', $wordid) 
     ->orderBy('created_at', 'desc')->get(); 

     if (!$words->isEmpty()) { 

      $theView = View::make('words.index', ['words' => $words])->render(); 

      if (is_object($words[0])) { 
       $theView .= '<script> 
       $(".lastWordId").removeClass($(".lastWordId").attr("class") 
       .split(" ")[1]).addClass("'.$words[0]->id.'"); 
       </script>'; 
      } 

      return $theView; 

     } else { 
      sleep(2); 
     } 
    } 
} 

Ich verwende: PHP 5.5 und Apache 2.2.22

das Problem nicht scheinen außerhalb von Laravel aufzutreten (in keinem Laravel-Projekt).

Vielen Dank im Voraus.

Antwort

-6

Sie sollten den longpolling in der JavaScript tun und alle 2 Sekunden

var refreshIntervalId = setInterval(function() { 

    // perform AJAX request every 2 seconds 
    longpending = $.ajax({ 
     type: 'POST', 
     url: '/getNewWords', 
     data: { wordid: ""+$('.lastWordId').attr('class').split(' ')[1]+"" }, 
     async: true, 
     cache: false 
    }).done(function(data) { 
     // process JSON response 
     var obj = jQuery.parseJSON(data); 

     $("#words").prepend(obj.output); 
     if(obj.status) == 'complete' 
     clearInterval(refreshIntervalId); 
     startRefresh(); 
}); 

}, 2000); // end refreshInterval 

Dann

echo json_encode(array('status'=> 'incomplete', 'output'=>$theView)); 

nicht getestet diesen Code in Ihren PHP überprüfen, aber Sie sollen die Idee.

+5

Dies ist nicht lange Polling. Es ist nur Umfragen. –

+0

Der Grund, warum ich das so mache, ist, dass Sie bei Apache/PHP oft Verbindungszeitüberschreitungen bekommen, indem Sie eine Verbindung offen lassen. Besonders wenn Sie sich hinter einem Amazon Load Balancer befinden, wird die Verbindung nach 30 Sekunden beendet. IMO besser alle paar Sekunden abzufragen. – bonez

+0

Polling ist einfach. Langes Polling ist in PHP zumindest schwer. – doncadavona

5

Eigentlich ist es nicht lange polling, wenn Sie Bonez-Code verwenden. Long Polling ist, wenn die Verbindung geöffnet bleibt (möglicherweise mit einer Zeitüberschreitung), bis der Server eine Antwort sendet. Wenn der Client alle 2 Sekunden eine Anfrage sendet und eine Antwort erhält, wird nur abgefragt und die Serverantwort wird im schlimmsten Fall 2 Sekunden später gemeldet. Bei langem Polling haben Sie diese Verzögerung nicht.

Das Einfrieren Problem ist kein Fehler mit Laravel. Die Sitzung blockiert. Also benutze session_write_close(); bevor Sie die Long-Polling-Methode aufrufen oder den Cookie-Session-Treiber verwenden. Weitere Informationen finden Sie unter http://konrness.com/php5/how-to-prevent-blocking-php-requests/

+0

Funktioniert 'session_write_close()' in Laravel? Er nennt es schon .. – daVe