Подтвердить что ты не робот

События, отправленные сервером: как вы автоматически подключаетесь к кросс-браузеру?

Я реализую некоторый код для запроса базы данных для любых изменений и отправки события. Здесь код моего PHP скрипт

header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');

//****Some code here to query the database

echo "event: message\n";
echo "data: change_from_database \n";
echo "\n\n";
ob_flush();
flush();

Я полагаюсь на браузер, чтобы автоматически подключаться каждый раз, когда соединение закрывается, поэтому я не реализую какой-либо цикл на моем сервере. Кроме того, я узнал из этой темы, что реализация бесконечного цикла имеет много недостатков.

Итак, все работает отлично на стороне клиента: браузер восстанавливается каждый раз, когда соединение закрывается, и событие запускается каждый раз, когда сервер отправляет его; хорошо, за исключением Firefox (40.0.2), который не пересоединяется. Я знаю, что это не потому, что я написал код проверки ошибок JavaScript, чтобы проверить это:

var evtSource = new EventSource("../sse.php");
evtSource.onerror = function(event){
    var txt;
    switch( event.target.readyState ){
    case EventSource.CONNECTING:
        txt = 'Reconnecting...';
        break;
    }
    console.log(txt);
}

Итак, как и каждую секунду, консоль на хроме, например, регистрирует "Reconnecting". Firefox, с другой стороны, снова соединяется и никогда не делает этого снова.

Как написать код, чтобы сделать эту работу в Firefox и, возможно, в других браузерах, которые поддерживают события, отправленные сервером, но не подключаются автоматически?

4b9b3361

Ответ 1

Вы можете использовать polyfill как этот https://github.com/Yaffle/EventSource, который должен добавить функциональность источника события в неподдерживаемые браузеры.

Ответ 2

В последней версии браузера Firefox (44.0.2) ваш код работает отлично. Однако вы можете повторно инициализировать свой объект EventSource в обработчике ошибок следующим образом:

var evtSource = new EventSource("../sse.php");
var evtSourceErrorHandler = function(event){
    var txt;
    switch( event.target.readyState ){
        case EventSource.CONNECTING:
            txt = 'Reconnecting...';
            break;
        case EventSource.CLOSED:
            txt = 'Reinitializing...';
            evtSource = new EventSource("../sse.php");
            evtSource.onerror = evtSourceErrorHandler;
            break;
    }
    console.log(txt);
}

Но я настоятельно не рекомендую вам делать это, потому что ваш код не использует преимущества поддержания соединения в живых (как вы писали, вы знаете о бесконечном цикле), поэтому браузер выполняет простой опрос (вы можете видеть это в вкладка сети). Я не вижу причин использовать SSE над AJAX, не сохраняя постоянного соединения, что, очевидно, сложно поддерживать с PHP. Поэтому я предполагаю использовать простой опрос AJAX в этой ситуации.

Ответ 3

Пройдите тест с кодом на моем сайте, и все работает как ожидается с Firefox 44.0.2 и php 5.5. Я действительно столкнулся с чем-то интересным в сети Mozilla dev, хотя это говорит о том, что вы не можете сказать, что сообщение об ошибке было в Firefox прошлого v22. Возможно, ваш оператор switch в проверке ошибок - это то, что вас отпустило. Здесь ссылка на статью . Проверьте раздел обработки ошибок.

Мой php-код идентичен вашему. На всякий случай я сделал что-то другое, вот мой html-код.

<!DOCTYPE>
<html>
<head>
    <title>SSE Test</title>
    <meta charset="utf-8" />
    <script>
      var evtSource = new EventSource("sse.php");
      evtSource.onerror = function(event){
        var txt;
        switch( event.target.readyState ){
           case EventSource.CONNECTING:
               txt = 'Reconnecting...';
               break;
        }
        console.log(txt);
      };
    </script>
  </head>
  <body></body>
</html>