10

首先说这在我的本地机器上完美运行,下面的 js 示例连接到 stream.php 并每秒接收服务器当前时间的连续更新。

索引.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);

流.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 "data: " . date( 'G:H:s', time() ) . PHP_EOL . PHP_EOL;

    // Toilet
    flush();

    // Wait one second.
    sleep(1);
}

上传到现场开发后,我确实预计会有一点延迟。服务器。但有大约 15 到 20 分钟的时间延迟。在我看到第一个条目之前。

连接不会断开。(可能已经进行了 40 分钟以上。)这只是一个 Apache 循环问题(意味着是时候查看 Web 套接字)还是我可以做些什么来解决这个问题?

4

4 回答 4

10

server.php 需要如下:

流.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);
}
于 2012-09-06T14:05:25.723 回答
2

睡眠阻塞了 SSE。我也有同样的问题。有人建议我使用事件驱动编程。

于 2014-02-19T18:33:42.640 回答
2

@Derrick,您建议的ob_end_flush();行让我很接近,但是在比 hello world 代码更复杂的 PHP 中,我仍然在我的 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);
}
于 2012-09-13T17:52:49.303 回答
0

只需添加 ob_flush(); 在 stream.php 中的 flush() 函数之前

更新的 stream.php 脚本如下,在 flush() 函数之前观察 ob_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);
}
于 2014-06-26T08:25:46.820 回答