Answer the question
In order to leave comments, you need to log in
Long Polling getting into an infinite message loop?
Hello!
I'm trying to make a simple real-time private chat using Long Polling, long polling is used only to display fresh messages when both users are online in the dialogue.
Messages are stored in Mysql and duplicated in Memcached and read from it and sent to the client.
Now, when sending a message, I get into an endless loop, the same message comes endlessly.
It seems that the data in Memcached is not updated.
Actually here is the php code:
// масив хранящийся в Memcached
/*
[
'user' => [
'to_read' => false,
'from_read' => false,
'name', // Имя
'image', // Ссылка на фото
'bigImage' // Ссылка на фото
],
'message' => [
'to' ,// id получателя
'from' ,// id отправителя
'text',// сообщение
'date' // дата сообщения
]
];
*/
$this->response->setContentType('application/json');
set_time_limit(0);
if ($this->request->isAjax() or $this->request->isPost())
{
$thisDialogueModel;
$sqlQuery; // hash
$sqlMemCache = md5($sqlQuery);
while (true)
{
if(!$this->auth->logged_in())
{
echo json_encode([
'type' => 'ERROR',
'message' => 'Auth error',
'data' => 'Auth error',
'timestamp' => ''
]);
sleep(1);
continue;
}
session_write_close();
/*
$this->cache;// это класс Phalcon\Cache\Backend\Memcache
https://docs.phalconphp.com/ru/latest/api/Phalcon_Cache_Backend_Memcache.html
*/
if($this->cache->exists($sqlMemCache))
{
$res = $this->cache->get($sqlMemCache);
if($res['message']['to'] == $this->auth->get_user()->id or $res['message']['from'] == $this->auth->get_user()->id)
{
$result = $this->responsePolingMessage($res, $this->auth->get_user()->id, $sqlQuery);
}
else
{
$result = array(
'type' => 'ERROR',
'message' => 'Security error',
'data' => 'Security error',
'timestamp' => null
);
}
echo json_encode($result);
unset($res);
unset($secErr);
unset($result);
break;
}
else
{
sleep(1);
continue;
}
}
}
else
{
}
// вспомогрательные методы
public function responsePolingMessage(array $data, $currentUserId, $memHash)
{
if($data['message']['to'] == (int)$currentUserId)
{
if($data['user']['from_read'] == true)
{
$result = array(
'type' => 'SUCCESS',
'message' => 'ok',
'data' => $data,
'timestamp' => time()
);
$this->cache->delete($memHash);
return $result;
}
elseif($data['user']['from_read'] == false)
{
$result = array(
'type' => 'SUCCESS',
'message' => 'ok',
'data' => $data,
'timestamp' => time()
);
$this->memDataUpdate('to', $data, true, $memHash);
return $result;
}
}
elseif($data['message']['from'] == (int)$currentUserId)
{
if($data['user']['to_read'] == true)
{
$result = array(
'type' => 'SUCCESS',
'message' => 'ok',
'data' => $data,
'timestamp' => time()
);
$this->cache->delete($memHash);
return $result;
}
elseif($data['user']['to_read'] == false)
{
$result = array(
'type' => 'SUCCESS',
'message' => 'ok',
'data' => $data,
'timestamp' => time()
);
$this->memDataUpdate('from', $data, true, $memHash);
return $result;
}
}
}
public function memDataUpdate($subject, array $data, $read, $memHash){
if($subject == 'from')
{
$this->cache->delete($memHash);
$data['user']['from_read'] = $read;
$this->cache->save($memHash,$data);
}
elseif($subject == 'to')
{
$this->cache->delete($memHash);
$data['user']['to_read'] = $read;
$this->cache->save($memHash,$data);
}
else
{
return false;
}
}
(function poll(timestamp){
var dialogueId = $('#msgWrap').attr('data-dialog');
var queryString = {
'timestamp' : timestamp,
'user_id' : $('#msgWrap').attr('data-user')
};
$.ajax({
type: 'POST',
url: '/messages/take/' + dialogueId,
success: function(data){
if(data.type === "ERROR")
{
alert(data.message);
}
else if(data.type === "SUCCESS")
{
if(data.data.message.from == queryString.user_id)
{
newMessage(data,true);
}
else if(data.data.message.to == queryString.user_id)
{
newMessage(data,false);
}
document.getElementById("msgWrap").scrollTop = 9999;
}
},
async: true,
dataType: "json",
complete: poll,
timeout: 30000
});
})();
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question