Соединение с отправленными событиями PHP-сервера не закрывается?

Я реализовал события, отправленные сервером с eventource в моем веб-приложении. В основном в javascript мой код выглядит так:

    var myEventSource;
    if (typeof(EventSource) !== "undefined" && !myJsIssetFunction(viridem.serverSideEvent.config.reindexProcessingEvent)) {
        myEventSource = new EventSource('/my/url/path.php?event=myevent');
        EventSource.onmessage = function(e) {
          [...] //Dealing with e.data that i received ...
        }
    }

на стороне PHP у меня есть что-то вроде этого:

<?php
  header('Content-Type: text/event-stream');
  header('Cache-Control: no-cache');
  header("Access-Control-Allow-Origin: *");

  //this or set_the_limit don't work but whatever I can deal without it
  ini_set('max_execution_time', 300);
  //ignore_user_abort(true); tried with true and false

  bool $mustQuit = false;

  while (!$mustQuit && connection_status() == CONNECTION_NORMAL) {
     if(connection_aborted()){
      exit();
     }
     [...] //doing some checkup

    if ($hasChange) {
      //Output stuffs
      echo 'data:';
      echo json_encode($result);
      echo "\n\n";
      ob_flush();
      flush();
      sleep(5);
    }

  }

из ответа, найденного по адресу: Источник событий PHP продолжает выполняться, "text / event- stream "заголовки должны закрывать соединение автоматически, но в моем случае этого не происходит.

Я добавил eventource.close в событие window.onbeforeunload, но он не закрыл событие.

window.onbeforeunload =  function() {
    myEventSource.close();
    myEventSource = null;
};

Если я посмотрю в сетевой раздел своего браузера, я вижу, что заголовки (после добавления максимального цикла 30): Content-Type: text / event-stream; charset = UTF-8

Заголовки ответа:

Доступ-Контроль-Разрешить-Происхождение: *

Cache-Control: без кеширования

Подключение: Keep-Alive

Тип содержимого: текст / поток событий; кодировка = UTF-8

Сервер: Apache / 2.4.18 (Ubuntu)

Дата: чт, 26 апр 2018, 20:29:46 GMT

Истекает: Thu, 19 Nov 1981 08:52:00 GMT

Заголовки запроса:

Подключение: keep-alive

Принять: текст / поток событий

Cache-Control: без кеширования

Примечание: я подтверждаю, что сценарий все еще работает с журналами и проверкой процесса apache2 с помощью bash (ps -ax | grep -c apache2), которые всегда увеличиваются.


person Jordan Daigle    schedule 26.04.2018    source источник
comment
Просто сделай while (true) { if (connection_aborted()) { exit(); Я использовал это какое-то время и отлично убивает процесс. Например: stackoverflow.com/a/49081040/661872   -  person Lawrence Cherone    schedule 26.04.2018
comment
connection_aborted () всегда возвращает int (0): /   -  person Jordan Daigle    schedule 27.04.2018
comment
Не уверен, как вы это тестируете, но вам также нужно ignore_user_abort (true); который у вас выключен.   -  person Lawrence Cherone    schedule 27.04.2018
comment
И вы не должны использовать max_execution_time   -  person Lawrence Cherone    schedule 27.04.2018
comment
Я закончил использовать максимальное количество циклов вместо максимального времени выполнения и set_time_limit, потому что это не остановило непрерывный запуск скрипта .. Думаю, я установлю их на бесконечное время выполнения или удалю их.   -  person Jordan Daigle    schedule 27.04.2018
comment
Идея состоит в том, что он работает непрерывно и завершается только после отключения клиента ... вы можете поместить в цикл проверку, которая защищает от перегрузки, например github.com/lcherone/sse-chat-example/blob/master/sse.php#L89, но это не будет необходимо в большинстве случаев .. как connection_aborted работает нормально.   -  person Lawrence Cherone    schedule 27.04.2018
comment
Вы были правы насчет connection_aborted, но мне не хватает вывода данных, чтобы эта функция работала. Я предполагаю, что иначе сервер не будет тыкать в клиента и тогда не узнает, активно ли соединение.   -  person Jordan Daigle    schedule 27.04.2018


Ответы (1)


Благодаря помощи @LawrenceCherone я обнаружил, что вам нужно выводить данные для работы connection_aborted ...

В моем случае я выводил данные только тогда, когда мне нужно было ...

добавляя

   if ($hasChange) {
      //Output stuffs
      echo 'data:';
      echo json_encode($result);
      echo "\n\n";
      ob_flush();
      flush();
      sleep(5);

    } else {
       echo 'data:';
       echo "\n\n";
       ob_flush();
       flush();
       if(connection_aborted()){
         exit();
       }
       sleep(5);
    }

connection_aborted начал работать.

person Jordan Daigle    schedule 26.04.2018
comment
Вам просто нужно убедиться, что вы также регулярно отправляете сообщение о сохранении активности. Обычно не чаще, чем каждые 40 секунд. Это гарантирует, что connection_abordted () будет задерживаться не более чем на 40 секунд. - person asiby; 30.07.2020