服务器发送事件工作,但有很长的时间延迟

时间:2012-09-06 10:11:04

标签: php apache server-sent-events

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

的index.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);

stream.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);
}

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

连接不会丢失。 (问题。已经过了40分钟+现在。)这只是一个Apache循环问题(意味着是时候查看网络套接字)还是我可以做些什么来解决这个问题?

4 个答案:

答案 0 :(得分:9)

Server.php需要如下:

stream.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);
}

答案 1 :(得分:1)

@Derrick,你建议的ob_end_flush();行让我接近,但是在比你好的世界代码更复杂的PHP中,我仍然在我的SSE连接上得到了不必要的重新打开(我仍然不完全理解为什么{{1这对我来说是这样的)。所以这是我现在使用的模式(否则与您的stream.php相同)。在英语中,我在进入无限循环之前关闭PHP输出缓冲:

ob_end_flush()

答案 2 :(得分:1)

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

答案 3 :(得分: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);
}