Длительный опрос в чате Laravel: почему div не обновляется?

Я пытаюсь создать приложение чата laravel с длинным опросом (я знаю, что есть nodejs / redis, но есть проблема ), и поэтому я пытался реализовать этот пример в Laravel и MySQL.

Однако запрос статуса AJAX GET всегда застрял в pending... Я решил, что это может быть причиной того, что он не обновляет div, где я показываю новое новое введенное значение из запроса POST AJAX на той же странице. В настоящее время div обновляется только при обновлении.

Вот мои коды:

Посмотреть

 function getMsg(timestamp){ var queryString = {"timestamp":timestamp}; $.get( "create", queryString, function(data){ var obj = $.parseJSON(data); console.log(obj.timestamp); $('#response').append('<p>'+obj.body+'</p>'); getMsg(obj.timestamp); } ).fail( function(xhr, textStatus, errorThrown) { alert(xhr.responseText); }); } getMsg(); . function getMsg(timestamp){ var queryString = {"timestamp":timestamp}; $.get( "create", queryString, function(data){ var obj = $.parseJSON(data); console.log(obj.timestamp); $('#response').append('<p>'+obj.body+'</p>'); getMsg(obj.timestamp); } ).fail( function(xhr, textStatus, errorThrown) { alert(xhr.responseText); }); } getMsg(); 

контроллер

 public function create() { $Msg = new Chatting; if(Request::ajax()){ set_time_limit(0); session_write_close(); while(true){ $last_ajax_call = isset($_GET['timestamp'])?(int)$_GET['timestamp']:null; clearstatcache(); $last_timestamp = $Msg->select(array('created_at'))->orderBy('created_at','desc')->first(); $last_change = json_decode($last_timestamp); if($last_ajax_call == null || $last_change->created_at > $last_ajax_call){ $result = array( 'body'=> $Msg->select('body','created_at')->where('created_at','=',$last_change->created_at)->first()->body, 'timestamp'=> $last_change->created_at ); $json = json_encode($result); echo $json; break; }else{ sleep(1); } } }else{ $msgdata = $Msg->select(array('created_at','body'))->orderBy('created_at','asc')->get(); return View::make('brightcms.Chatting.Chatting',compact('msgdata')); } } в public function create() { $Msg = new Chatting; if(Request::ajax()){ set_time_limit(0); session_write_close(); while(true){ $last_ajax_call = isset($_GET['timestamp'])?(int)$_GET['timestamp']:null; clearstatcache(); $last_timestamp = $Msg->select(array('created_at'))->orderBy('created_at','desc')->first(); $last_change = json_decode($last_timestamp); if($last_ajax_call == null || $last_change->created_at > $last_ajax_call){ $result = array( 'body'=> $Msg->select('body','created_at')->where('created_at','=',$last_change->created_at)->first()->body, 'timestamp'=> $last_change->created_at ); $json = json_encode($result); echo $json; break; }else{ sleep(1); } } }else{ $msgdata = $Msg->select(array('created_at','body'))->orderBy('created_at','asc')->get(); return View::make('brightcms.Chatting.Chatting',compact('msgdata')); } } 

Заголовок запроса GET

 Request URL:http://localhost/msgsys/public/cms/Chatting/create?timestamp=2014-06-09+06%3A49%3A11 Request Headers CAUTION: Provisional headers are shown. Accept:*/* Cache-Control:no-cache Pragma:no-cache Referer:http://localhost/msgsys/public/cms/Chatting/create Chrome/35.0.1916.114 Safari/537.36 X-Requested-With:XMLHttpRequest Query String Parametersview sourceview URL encoded timestamp:2014-06-09 06:49:11 

Btw, бонусные баллы за лучшие способы:

  1. Улучшите код, чтобы он максимально использовал функции и возможности Laravel 4.
  2. Запустите NodeJS на dreamhost / shared сервере без каких-либо ограничений. В настоящее время есть эта проблема .

Итак, как я могу исправить свой код, чтобы при вводе нового значения приложение обновляло div, чтобы отображать вновь введенное значение, например, приложение реального времени?

Я все еще новичок в Laravel и буду благодарен критике / советам. Большое спасибо!

Из того, что я вижу, я думаю, что здесь бесконечная петля.

PHP и сокеты

Если вы не можете использовать NodeJS, попробуйте PHP с помощью Sockets. Должен работать для этого очень хорошо!

улучшения

Вы сказали, что ищете улучшения. Вот они.
Плюс я бы использовал Angular для привязки данных, полученных с сервера к представлению.

Файл вида

 <html> <head> <title></title> {{ HTML::script('//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js') }} <style> #chat { width: 300px; } #input { border: 1px solid #ccc; width: 100%; height: 30px; } #messages { padding-top: 5px; } #messages > div { background: #eee; padding: 10px; margin-bottom: 5px; border-radius: 4px; } </style> </head> <body> <div id="chat"> <input id="input" type="text" name="message" value=""> <div id="messages"> </div> </div> <script> var $messagesWrapper = $('#messages'); // Append message to the wrapper, // which holds the conversation. var appendMessage = function(data) { var message = document.createElement('div'); message.innerHTML = data.body; message.dataset.created_at = data.created_at; $messagesWrapper.append(message); }; // Load messages from the server. // After request is completed, queue // another call var updateMessages = function() { var lastMessage = $messagesWrapper.find('> div:last-child')[0]; $.ajax({ type: "POST", url: '{{ url('chat/refresh') }}', data: { from: ! lastMessage ? '' : lastMessage.dataset.created_at }, success: function(messages) { $.each(messages, function() { appendMessage(this); }); }, error: function() { console.log('Ooops, something happened!'); }, complete: function() { window.setTimeout(updateMessages, 2000); }, dataType: 'json' }); }; // Send message to server. // Server returns this message and message // is appended to the conversation. var sendMessage = function(input) { if (input.value.trim() === '') { return; } input.disabled = true; $.ajax({ type: "POST", url: '{{ url('/chat') }}', data: { message: input.value }, success: function(message) { appendMessage(message); }, error: function() { alert('Ooops, something happened!'); }, complete: function() { input.value = ''; input.disabled = false; }, dataType: 'json' }); }; // Send message to the servet on enter $('#input').on('keypress', function(e) { // Enter is pressed if (e.charCode === 13) { e.preventDefault(); sendMessage(this); } }); // Start loop which get messages from server. updateMessages(); </script> </body> </html> 

Маршруты

 Route::post('chat/refresh', function() { $from = Input::get('from', null); if (is_null($from)) { $messages = Message::take(10); } else { $messages = Message::where('created_at', '>', $from); } return $messages->latest()->get(); }); Route::post('chat', function() { return Message::create(['body' => Input::get('message')]); }); Route::get('chat', function() { return View::make('chat'); }); 

Модель

 class Message extends Eloquent { protected $fillable = ['body']; } 

Я думаю, код довольно напряженно … Комментарии должны объяснить все.