nepster-web
@nepster-web

Несколько вопросов по работе с библиотекой EventSource?

Использую вот эту вещь https://github.com/Yaffle/EventSource
Более менее разобрался, что к чему. Но все же есть несколько вопросов для понимания.


Вопрос номер 1, для чего нужен цикл ?


header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header("Access-Control-Allow-Origin: *");
        
        $start = time();
        
        $lastEventId = floatval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0);
        if ($lastEventId == 0) 
        {
            $lastEventId = (isset($_GET["key"])) ? (string)$_GET["key"] : 0;
        }
        
        $id = 0;
        
        while(true) 
        {
            if ((time() - $start) > 10) 
            {
                break;
            }
        
            $updateProposals = array($id);
        
            //echo ":" . str_repeat(" ", 2048) . "\n"; // 2 kB padding for IE
            echo "retry: 2000\n";
            echo "id: {$lastEventId}" . PHP_EOL;
            echo "data: " . ProcessingData::load()->getJson($updateProposals) . PHP_EOL;
            echo PHP_EOL;
            
            ob_flush();
            flush();
            
            
            $id += 1;
            sleep(4);
        }


Имеется вот такой код. Он работает и соединение держит 10 секунд.
Если же убрать данный цикл, то после каждой отдачи данных будет реконект. Даже если оставить
ob_flush();
flush();

Подскажите пожалуйста зачем тут использовать цикл ?


вопрос 2, обрыв соединения
После того как истекает 10 секунд, идет реконект.
Тогда выбрасывается экшин еррор в js

var es = new EventSource("/games/game/updateProposals/?id=<?=$game->game_id?>");
  
                    var open = function (event) 
                    {
                        console.log('Открытие');
                    }; 
                    
                    var listener = function (event) 
                    {
                        console.log('OK');
                        $('.test').html(Math.random());
                    };  
                        
                    var error = function (event) 
                    {
                        //if (event.readyState == EventSource.CLOSED) 
                        if (EventSource.CLOSED == 2) 
                        {
                            console.log('Соединение закрыто');
                        }            
                        else
                        {
                            console.log('Другая ошибка');
                        }    
                    }; 
                
                    
                    es.addEventListener("open", open);
                    es.addEventListener("message", listener);
                    es.addEventListener("error", error);


Причем тут такой момент, что в документации написано event.readyState, хотя на самом деле приходит event.target.event.readyState со значением 2 и идет реконект снова на 10 секунд.

Далее если убрать код:
if ((time() - $start) > 10) 
            {
                break;
            }


То реконект будет примерно через секунд 30.
Подскажите пожалуйста почему реконект происходит в любом случае, даже если мы не делаем выходом из цикла

И вопрос номер 3. Как лучше всего сделать обновление в реал тайме с помощью данной библиотеки, сколько секунд будет оптимально держать соединение, какая должна быть чистота обновления (тоесть раз в сколько секунд посылать запрос), как часто нужно делать реконект ?

Просьба node.js не предлагать, так как у меня нода используется уже после всего.
Для справки. Когда пользователь находится на сайте (на странице заявок игры или ожидает соперника) мы обновляем данные, что бы он видел кто присоединился к заявке и тп. После тогда как заявка уже сформирована по кнопке играть пользователь улетает в игру, которая уже и использует ноду.
  • Вопрос задан
  • 3257 просмотров
Пригласить эксперта
Ответы на вопрос 1
avalak
@avalak
0. Библиотека о которой вы каждый раз упоминаете - polyfill. Она нужна для реализации SSE в старых и кривых браузерах. Нет смысла писать о ней каждый раз (особенно учитывая что вы пытаетесь сделать сервер).

1. Это демо из библиотеки. Просто чтобы посмотреть что библиотека работает.

Подскажите пожалуйста зачем тут использовать цикл ?

Я даже не знаю что на это ответить. Цикл нужен чтобы циклически выполнять действия. Ваш КО.

Что происходит в цикле:
- если прошло больше 10 секунд завершаем работу
- пишем данные
- сбрасываем буфер
- спим 4 секунды

Если же убрать данный цикл, то после каждой отдачи данных будет реконект

А чего вы ждали? Скрипт выполнил свою работу и умер.

Даже если оставить
ob_flush();
flush();

Это для принудительной отправки данных пользователю.

То реконект будет примерно через секунд 30.

Время жизни php ограниченно. Он создан чтобы умирать. Умирать через 30 секунд (вероятно именно 30 секунд указанно в настройках).

И вопрос номер 3. Как лучше всего сделать обновление в реал тайме с помощью данной библиотеки, сколько секунд будет оптимально держать соединение, какая должна быть чистота обновления (тоесть раз в сколько секунд посылать запрос), как часто нужно делать реконект ?


Ещё раз. Это библиотека для браузера. В случае с SSE соединение не должно разрываться. В вашем случае оно разрывается из-за использования php.
Чтобы не разрывалось (оптимальное применение) нужно использовать node, tornado или что-то подобное
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы