я пытаюсь выучить серверные события на тел.
Сначала почти каждый пример имел цикл на стороне сервера и возвращал значение с помощью ob_flush () / flush (). Поэтому я попытался сделать так:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// Output a 'waiting message'
$progress = 0;
while ($progress < 100) {
echo 'data:';
echo $progress;
echo "\n\n";
flush();
ob_flush(); //I tried ob_implicit_flush(true) too
$progress++;
sleep(1);
}
?>
И JavaScript
function start(btn) {
var source = new EventSource('/fix/streamingGet.php');
source.onmessage = function(e) {
console.log(e.data);
};
}
Но ничего не было получено, пока сценарий не был закончен …
так что я закончил тем, что пытался без бесконечного цикла, и все работает
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// Output a 'waiting message'
echo 'data:';
echo rand(5, 15);
echo "\n\n";
?>
Редактировать: Неважно, я, вероятно, где-то сделал ошибку, потому что теперь это работает
Редактировать: я имел в виду цикл, возвращающий несколько результатов с помощью ob_flush / flush (не бесконечный цикл, мой плохой)
Но нужно ли мне возвращать мои данные с многократной очисткой, чтобы повысить производительность Серверная сторона ?
Обновить :
Из моих тестов и исследований кажется, что php не позволяет нескольким сессиям, которые делают первый пример, чтобы заблокировать любой другой вызов к серверу. Таким образом, единственное работающее решение php, кажется, возвращает значение каждый раз. Я думаю, это то же самое, что иметь несколько синхронизированных ajax-вызовов к серверу.
Я предполагаю, что если я действительно хочу передать значение с сервера, то мне, вероятно, следует использовать nodejs на стороне моего веб-приложения.
То, что вы делаете, в основном правильно.
Но поставить ob_flush()
до flush()
(так как ob_flush()
сбрасывает PHP-буферы в Apache, а затем flush()
говорит Apache отправить его буферизованный контент для клиента) и его более надежно поставить @
до ob_flush()
(потому что если вы отключили буферизацию PHP, вы можете получить сообщение об ошибке — @
подавляет это).
(Комментарии неверны об использовании бесконечных циклов в PHP: в этом случае они хороши. Когда клиент браузера отключается, Apache убьет экземпляр PHP. Нет утечки памяти только из-за выполнения бесконечного / долго работающего цикла.)
Блокировка сессий PHP. Поэтому, если один и тот же пользователь (тот же сеанс) может получить доступ к какой-либо другой части вашего сайта во время отправки данных сценарием SSE, вам потребуется сценарий SSE, чтобы прекратить использование сеансов. Итак, возьмите любые данные, которые вам нужны из сеанса в верхней части вашего скрипта, затем вызовите session_write_close()
перед входом в основной цикл. Увидеть https://stackoverflow.com/a/19440378/841830
Других решений пока нет …