EventSource: всегда получаю ошибку

Чтобы начать работу с EventSource API, я написал самый схоластический пример. Проблема в том, что я всегда получаю сообщение об ошибке и не могу найти никакой полезной информации об этом. Когда я загружаю home.html, сценарий JS останавливается на source.onerror; Я печатаю его в консоли, но анализируя объект, я не могу найти какой-либо тип ошибки или сообщение, поэтому я понятия не имею, что это не так. Есть ли ошибка в коде? Может быть ошибка связана с сервером?


home.html

<body>
  <div id="result"></div>
  <script src="sse.js"></script>
</body>

sse.js

function isSseEnabled() {
    return (typeof EventSource !== "undefined");
}

if (isSseEnabled()) {
    var source = new EventSource('source.php');
    source.onerror = function(e) {
        console.log(e);
        source.close();
    };
    source.onmessage = function (e) {
        console.log(e.data);
        document.getElementById('result').innerHTML += e.data.concat('<br>');
    }
} else {
    throw 'SSE not enabled';
}

source.php

<?php
header('Content-Type: text/event-stream');
header('Cache-control: no-cache');

$time = date('r');
echo "Time: $time";
flush();

person Brigo    schedule 23.03.2018    source источник


Ответы (1)


(TLDR: вы не используете протокол SSE — см. вторую половину этого ответа.)

Первое, что вам нужно сделать, это получить правильное сообщение об ошибке или, по крайней мере, посмотреть, что создает ваш скрипт. Я бы предложил использовать curl для проверки вашего скрипта. Из командной строки:

curl http://127.0.0.1/source.php

(Я предположил, что и ваш html, и source.php находятся на вашем локальном компьютере и не используют https; если нет, настройте выше. Также настройте, чтобы добавить путь к source.php.)

Если это работает или у вас нет curl, посмотрите инструменты разработчика в своем браузере. Посмотрите, что происходит с подключением к source.php, что отправляется и что принимается.

Однако определенно есть несколько способов улучшить PHP-скрипт. Сначала добавьте к сообщению префикс «data:» и добавьте пару LF после каждого сообщения; это требуется протоколом SSE.

Во-вторых, используйте бесконечный цикл со сном в нем (никогда не имеет смысла иметь сценарий SSE, который возвращает что-то одно и закрывается - в этом случае вы можете просто использовать AJAX). Так это будет выглядеть так:

<?php
header('Content-Type: text/event-stream');
header('Cache-control: no-cache');

while(true){
    $time = date('r');
    echo "data:Time: $time\n\n";
    @ob_flush();flush();
    sleep(1);
    }
person Darren Cook    schedule 26.03.2018