我正在尝试使用长轮询构建laravel聊天应用程序(我知道有nodejs / redis但存在问题),因此我一直在尝试将此示例实现到Laravel和MySQL中。
但是,AJAX GET状态请求 始终停留 在pending...。我发现这可能是因为它没有更新div的原因,在div上我在同一页面上显示了来自AJAX POST请求的新输入的新值。当前,div仅在刷新时进行更新。
pending...
这是我的代码:
视图
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')); } }
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
顺便说一句,最佳方法的奖励积分:
是的,我该如何修复代码,以便在输入新值时,应用程序将更新div以像实时应用程序一样显示新输入的值?
我在Laravel还是很新,很感谢批评/建议。非常感谢你!
从我看来,我认为无限while循环是这里的问题。
while
如果您不能使用NodeJS,请尝试使用带套接字的PHP。应该可以很好地工作!
您说您正在寻找改进。他们来了。 另外,我将使用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']; }
我认为,代码很简单……注释应能解释所有内容。