为什么我的聊天应用有时无法接收消息?

时间:2014-07-17 07:59:47

标签: php mysql laravel polling

我正在构建聊天网络应用程序并使用间隔轮询。但是,有时客户端A 发送的消息不会被客户端B接收。这种情况就像发送的20封消息中的一次一样。客户端B上的页面刷新当然会导致加载消息。

这是它的工作原理:

我使用会话来存储客户端A最后一次轮询服务器的时间。当我进行下一次轮询时,服务器会检查数据库中是否有时间(精确到微秒)大于上次轮询时间的消息。在处理了最新消息之后,服务器会将当前时间保存在会话数据中,以用作下次即将进行的轮询的上次轮询时间。

我了解会话会私下保存数据,以便其他用户无法访问它。因此,两个客户端总是在不同的时间轮询同一台服务器。

出了什么问题?我应该使用缓存作为替代方案,以便两个客户端同时轮询同一个服务器吗? P.s.,我正在使用Apache服务器和MySQL数据库。

这里是laravel中的轮询代码:

   public function index(){

        $currentPoll = round(microtime(true) * 1000);//calculate the current time in microseconds

        //if the session variable doesn't exist, set the lastPoll variable to 0
        if(!($lastPoll = Session::get('lastPoll'))){
              $lastPoll = 0;
        }

        $selectedMsgExists = Input::get('selectedMsgExists');//check whether messages exist in currently opened conversation

        //check if conversation is opened or not
        if(Input::has('selectedID')){
            $selectedID = Input::get('selectedID');
        }
        else{
            $selectedID = false;
        }

        $loginuser = User::find(Auth::user()->id);//get the currently logged in user
        if($selectedMsgExists=='false'&&$selectedID){
        //if messages has not been loaded but conversation exists, we take the first ten messages of the opened conversation.

            $allMessages = $loginuser->messages()->select('users.name')->join('users',function($join){
                $join->on('users.id','=','messages.user_id');
            })->where('conv_id','LIKE',$selectedID)->orderBy('microseconds','desc')->take(10);

            Session::put('lastPoll',$currentPoll);//save the session
            return array(false,$allMessages->get()->reverse());//return the latest messages. False is to indicate that the data returned is NOT a conversation
        }
}

1 个答案:

答案 0 :(得分:0)

使用ID,而不是时间!

我会在上面的评论中赞扬judereid

Another thing to consider... I would be most suspicious of querying by a timestamp 
here. If for some reason there's even as much as a 1 microsecond overlap you could 
miss a message. Perhaps instead of logging the time you could log the last 
retrieved ID (assuming you have incrementing ids on the messages) and then poll 
for messages with ID greater than that –  judereid

经过一些调整,似乎没有任何消息不对。我想这个问题实际上是利用时间来获取最新消息。