Начнем с того, что это прекрасно работает на моей локальной машине, пример js ниже подключается к stream.php и получает непрерывное обновление серверов в текущее время каждую секунду.
var source = new EventSource("stream.php"); source.addEventListener('message', function(e) { console.log(e); }, false); source.addEventListener('open', function(e) { console.log(e); }, false); source.addEventListener('error', function(e) { if (e.readyState == EventSource.CLOSED) { console.log('closed'); } }, false);
while(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "data: " . date( 'G:H:s', time() ) . PHP_EOL . PHP_EOL; // Toilet flush(); // Wait one second. sleep(1); }
вwhile(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "data: " . date( 'G:H:s', time() ) . PHP_EOL . PHP_EOL; // Toilet flush(); // Wait one second. sleep(1); }
Я ожидал некоторую задержку после загрузки в live dev. сервер. Но есть временная задержка около 15-20 минут. прежде чем я увижу первую запись.
Соединение не падает. (Вероятно, сейчас 40 минут +.) Является ли это просто проблемой цикла Apache (значит, это время для поиска веб-сокетов), или я могу что-то сделать, чтобы исправить это?
Server.php должен быть следующим:
while(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "Event: server-time" . PHP_EOL; print "data: " . date( 'G:H:s', time() ) . PHP_EOL; print PHP_EOL; ob_end_flush(); // Strange behaviour, will not work flush(); // Unless both are called ! // Wait one second. sleep(1); }
вwhile(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "Event: server-time" . PHP_EOL; print "data: " . date( 'G:H:s', time() ) . PHP_EOL; print PHP_EOL; ob_end_flush(); // Strange behaviour, will not work flush(); // Unless both are called ! // Wait one second. sleep(1); }
@Derrick, ваш предлагаемый ob_end_flush();
линия меня закрыла, но в более сложном PHP, чем hello world code, я все еще получал нежелательные повторные открытия в моих SSE-соединениях (я до сих пор не совсем понимаю, почему ob_end_flush()
делает это со мной). Итак, вот шаблон, который я использую (в противном случае он идентичен вашему stream.php). На английском языке я отключу буферизацию вывода PHP, прежде чем вводить мой бесконечный цикл:
// per http://www.php.net/manual/en/book.outcontrol.php: // Clean (erase) the output buffer and turn off output buffering ob_end_clean(); // how long PHP script stays running/SSE connection stays open (seconds) set_time_limit(60); while (true) { // use @Derrick's header/send code here ob_flush(); // note I don't turn off output buffering here again flush(); sleep(1); }
Сон блокирует SSE. У меня тоже была такая же проблема. Мне было рекомендовано использовать программирование, управляемое событиями.
просто добавьте, ob_flush (); перед функцией flush () в stream.php
обновленный сценарий stream.php приведен ниже, наблюдайте функцию ob_flush () перед функцией flush ().
while(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "data: " . date( 'G:H:s', time() ) . PHP_EOL . PHP_EOL; // Toilet **ob_flush();** flush(); // Wait one second. sleep(1); }
вwhile(true) { // Headers must be processed line by line. header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // Set data line print "data: " . date( 'G:H:s', time() ) . PHP_EOL . PHP_EOL; // Toilet **ob_flush();** flush(); // Wait one second. sleep(1); }