За последние 24 часа нас посетили 111346 программистов и 6480 роботов. Сейчас ищут 1343 программиста ...

Не могу разобраться с longpolling.....

Тема в разделе "PHP для новичков", создана пользователем KnaviBebus, 10 сен 2018.

Метки:
  1. KnaviBebus

    KnaviBebus Новичок

    С нами с:
    10 сен 2018
    Сообщения:
    4
    Симпатии:
    0
    Здравствуйте, столкнулся с такой проблемой.... Решил я заняться изучением long polling, естественно чтобы попрактиковаться стал писать чатик :)
    Алгоритм скрипта примерно такой: в базе данных sqlite есть таблица с сообщениями. Приложение клиента отправляет количество сообщений которое у него уже есть (число). Скрипт записывает это число в переменную, затем с помощью sql запроса узнаёт сколько сообщений в базе данных. Если в БД сообщений больше чем у клиента, то скрипт получает из БД недостающие строки и отправляет их клиенту.
    Если проще: клиент прислал число 5, скрипт узнал что в БД 8 записей, значит клиенту он отправит 3 последние строки.
    Скрипт по этой схеме вполне себе работает, НО: в конце цикла есть функция sleep(2), которая должна создавать паузу между итерациями чтобы скрипт не начал флудить огромным количеством запросов. Проблема в том, что всё равно флудит! Да, клиент получает ответ от сервера через заданный в sleep() промежуток времени, со стороны кажется что всё в порядке. Когда я начал тестировать, то заметил что сервер через 10-15 минут после запуска скрипта обрывает соединение с ошибкой 503. Тогда я добавил в начало цикла переменную, значение которой увеличивалось на +1 с каждой итерацией, затем это число записывалось в файл. Оказалось, цикл срабатывает от 50 до 1000 раз в секунду, будто sleep() там нет.....
    Надеюсь на вашу помощь друзья, ковыряюсь уже с этим 3-й день, задавал этот вопрос в различных пабликах в ВК посвящённых php, все либо игнорили, либо скидывали ссылки на всякие книжки.
    Код:
    PHP:
    1. <?php
    2. $dbh = new PDO('sqlite:db.db3');
    3.         $dbh->exec("PRAGMA foreign_keys = ON;");
    4.     $dbh->exec("PRAGMA SQLITE_OPEN_NOMUTEX;");
    5.         $dbh->exec("PRAGMA encoding = 'UTF-8'");
    6.         $dbh->exec("PRAGMA journal_mode = WAL;");
    7.         $dbh->exec("PRAGMA synchronous = OFF");
    8. $number = (int) $_POST['number'];
    9. $action = $_POST['action'];
    10. switch ($action) {
    11. case 'update':
    12.  
    13. $live_time = microtime(true);
    14. $this_time = microtime(true)-$live_time;
    15.             if ($this_time >= 5) {
    16.                 // Закрываем соединение с базой
    17.                 $dbh = null;
    18.                $message = [
    19.                     'status' => 'no database'
    20.                    ];
    21.         echo json_encode($message, JSON_NUMERIC_CHECK);
    22.                 die();
    23.             }
    24.  
    25. while(true){
    26. sleep(1);
    27. $number_s = $dbh->query('SELECT COUNT(id) FROM Messages')->fetchColumn();
    28. if($number_s != $number){
    29.                         $amount = $number_s - $number;
    30.                          if($amount < 0){
    31.                          $amount = 0;
    32.                             $message = [
    33.                     'status' => 'clear',
    34.                         ];
    35.                     echo json_encode($message, JSON_NUMERIC_CHECK);
    36.                              die();
    37.                             }//конец if
    38.             $sth = $dbh->prepare("SELECT * FROM (SELECT * FROM Messages ORDER BY id DESC LIMIT ?) t ORDER BY id");
    39.                         $sth->execute(array($amount));
    40.                         $result = $sth->fetchAll();
    41.       $dbh = null;
    42.       // sleep(1);                  
    43.        break;
    44.   } //конец if
    45. sleep(2);
    46. } //конец while
    47. $message = [
    48.                     'status' => 'success',
    49.                     'sql' => $result
    50.                    ];
    51.         echo json_encode($message, JSON_NUMERIC_CHECK);
    52. break;
    53. } //конец switch
    54. $dbh = null;
    55.     die();
    56. ?>
     
  2. username

    username Новичок

    С нами с:
    6 июл 2017
    Сообщения:
    223
    Симпатии:
    17
    можно с помощью ajax делать запрос со страницы к скрипту, с целью получения новых сообщений, и повторять ajax запрос каждые 5 секунд
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    в 21 веке не юзают лонгпулинг по возможности
    юзай че другое - центрифугу, ноду
     
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    @username, чел хочет long pulling, а ты предлагаешь short.

    @KnaviBebus, согласен с @igordata, лучше пользовать веб-сокеты и технологии работы с ними. Браузеры, которые их не поддерживают, уже сдохли
     
  5. KnaviBebus

    KnaviBebus Новичок

    С нами с:
    10 сен 2018
    Сообщения:
    4
    Симпатии:
    0
    К скрипту обращается десктопное приложение, оно умеет только пост и гет запросы отправлять
     
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    @KnaviBebus, а AJAX - это что по твоему?

    А код вообще со странной логикой...