长轮询在Laravel聊天:为什么DIV没有更新自己? [英] Long-polling in Laravel chat: Why is the div not updating itself?

查看:596
本文介绍了长轮询在Laravel聊天:为什么DIV没有更新自己?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立与长轮询一个laravel聊天应用程序(我知道有<一href="http://www.volkomenjuist.nl/blog/2013/10/20/laravel-4-and-nodejsredis-pubsub-realtime-notifications/"相对=nofollow> nodejs / Redis的但有一个问题)和因此,我一直在努力实现这个例如到Laravel和MySQL。

I'm trying to build a laravel chat app with long-polling (I know there's nodejs/redis but there's a problem) and therefore I have been trying to implement this example into Laravel and MySQL.

然而,AJAX获取状态请求的总是卡住待... 。我想这可能是原因,它没有更新 在那里,我从在同一页上的AJAX POST请求显示我的新新输入值的股利。目前,格只更新自己的刷新。

However, the AJAX GET status request is always stuck at pending.... I figured this might be the cause that it is not updating the div where I display my new newly inputted value from an AJAX POST request on the same page. Currently, the div only updates itself on refresh.

下面是我的codeS:

Here are my codes :

查看

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

顺便说一句,加分的最佳途径:

Btw, bonus points for best ways to :

  1. 提高code所以,它使最出Laravel 4的功能和做的东西的方式。
  2. 在没有任何限制的Dreamhost /共享服务器上运行的NodeJS。目前,有此问题

所以呀,我怎么解决我的code,这样,当我输入一个新值,应用程序将更新一个div来显示一个类似的实时应用程序的新输入的值?

So yeah, how do I fix my code so that when I input a new value, the app will update a div to display the newly inputted value like a real-time app?

我仍然在Laravel很新,并会AP preciate批评/建议。非常感谢你!

I'm still quite new in Laravel and would appreciate criticisms/advises. Thank you very much!

推荐答案

这是我所看到的,我觉得无限的,而循环是这里的问题。

From what I see, I think infinite while loop is the problem here.

如果您不能使用NodeJS,尝试用插座PHP。如果此pretty的正常工作!

If you cannot use NodeJS, try out PHP with Sockets. Should work for this pretty well!

您说您搜索的改进。在这里,他们是。
另外,我会用角绑定从服务器检索到视图中的数据。

You said you search for improvements. Here they are.
Plus I would use Angular to bind data retrieved from server to the view.

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

我认为,code是pretty的straighforward ...评论应该解释一切。

I think, code is pretty straighforward... Comments should explain everything.

这篇关于长轮询在Laravel聊天:为什么DIV没有更新自己?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆