A
A
Aizharik2015-11-09 12:50:59
PHP
Aizharik, 2015-11-09 12:50:59

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;
        }

    }

and client:
(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
    });

})();

I think that the memDataUpdate() function does not work, it does not update the data in the memcache.
I work with long polling for the first time and Memcached too, I use it for the first time. therefore I ask for your help.
As for the code and architectural solution (if you can call it that), I ask for your suggestions for improvement.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Aizharik, 2015-12-15
@aizhar777

Who cares, refused long-polling. I use Ratchet with Push and extension ZeroMQ

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question