Здравствуйте!
Пытаюсь сделать простенький real-time private чат с использованием Long Polling, лон полинг используется только для вывода свежих сообщений когда в диалоге оба пользователя онлайн.
Сообщения храню в Mysql и дублирую в Memcached и из него же считываю и отправляю клиенту.
Сейчас при отправке сообщения попадаю в бесконечный цикл, одно и тоже сообщение приходит бесконечно.
Создается впечатление что данные в Memcached не обновляются.
Собственно вот код php:
// масив хранящийся в 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
});
})();
Думаю что не отрабатывает функция memDataUpdate(), не обнавляет данные в мемкеше.
С лонг полинг работаю в первые да и Memcached тоже, очно использую впервые. посему прошу вашей помощи.
Так же по коду и архитектурному решению(если можно так назвать), прошу ваших предложений для улучшения.