【问题标题】:Why is my chat app sometimes not receiving messages?为什么我的聊天应用有时收不到消息?
【发布时间】:2014-07-17 07:59:47
【问题描述】:

我正在构建一个聊天 Web 应用程序并使用间隔轮询。但是,有时客户端 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
        }
}

【问题讨论】:

  • 能否提供代码。我们看不到现在发生了什么。
  • @dwhite.me 提供代码
  • 您确定消息正在发布到数据库中吗?
  • @dwhite.me 绝对。就像我说的,客户端 B 上的页面刷新会导致消息被加载。
  • 另一件要考虑的事情......我最怀疑这里的时间戳查询。如果由于某种原因甚至有 1 微秒的重叠,您可能会错过一条消息。也许不是记录时间,您可以记录最后检索到的 ID(假设您在消息上有递增的 ID),然后轮询 ID 大于该 ID 的消息

标签: php mysql laravel polling


【解决方案1】:

使用 ID,而不是时间!

我会在上面的 cmets 中感谢 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

经过一些调整,似乎没有任何错误消息。我猜这个问题真的是用时间来获取最新消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    相关资源
    最近更新 更多