Я хочу написать в режиме реального времени сервер просмотра журнала и только что узнал о SSE. Я не совсем понимаю, как правильно его использовать. Я использую сервер Linux с php 5.4. У меня есть этот код прямо сейчас:
HTML + JS:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<ul id='el'></ul>
<script type="text/javascript">
var eSource = new EventSource("ssedemo.php");
eSource.onmessage = function(event) {
var e = document.createElement("li");
e.innerHTML = event.data;
document.getElementById('el').appendChild(e);
};
</script>
</body>
</html>
PHP:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
?>
Это работает, но оно сбрасывает соединение после каждого обновления, и клиент переустанавливает его каждые 3 секунды. Я хотел бы, чтобы он обновлялся быстрее. Из документации и учебных пособий в Интернете видно, что правильный способ использования SSE — это обернуть код сервера в цикл для поддержания соединения и использовать sleep
контролировать время обновления:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true) {
$time = date('r');
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
sleep(1);
};
?>
Проблема в том, что это не работает. Всякий раз, когда я ввожу цикл, onmessage
никогда не вызывается на стороне клиента. Я пробовал многочисленные примеры без изменения какого-либо кода (https://github.com/html5rocks/www.html5rocks.com/tree/master/content/tutorials/eventsource/basics/static/demo), (https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events) и т. д., но ни один из них не сработает, если я не удалю цикл из php.
Почему я не могу поддерживать связь? Что-то изменилось в php 5.4, что мешает этому работать?
Чтобы ответить на ваш последний вопрос первым, в php 5.4 не было никаких изменений, которые могли бы остановить эту работу.
Все выглядит правильно для меня. Вместо onmessage
Я всегда использовал это так:
eSource.addEventHandler('message', function(event) {
var e = document.createElement("li");
e.innerHTML = event.data;
document.getElementById('el').appendChild(e);
}, false);
Но я думаю, что в любом случае это хорошо. (Подтверждено, что вы говорите, что это работает, когда нет цикла while, и отправляется только один пакет данных.)
Итак, все, что я могу сделать, это предложить пару идей по устранению неполадок:
Можете ли вы использовать Firebug или консоль разработчика Chrome, чтобы посмотреть, что делает соединение?
Видите ли вы, что он закрывается немедленно (что может означать некоторую синтаксическую ошибку или другое падение в вашем PHP-скрипте), или он остается открытым всегда, но не получает никаких данных (что подразумевает кэширование на стороне сервера или промежуточный прокси-сервер)? кеширование на сервере), или он всегда остается открытым, и получает данные (что может указывать на то, что с вашим JavaScript что-то не так).
Также проверьте консоль JS на наличие предупреждений и проверьте журнал ошибок PHP на стороне сервера для предупреждений.
Других решений пока нет …