【发布时间】: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 的消息