HTML5 Server-Sent Events原型设计 - 模糊错误和重复轮询?

tom*_*umb 13 apache html5 server-push server-sent-events

我想它们符合我的要求完美,看起来他们应该是简单的实现获得与服务器端事件交手,但我不能让过去一个模糊的错误,什么样子反复被关闭了连接并重新-opened.我尝试的一切都基于这个和其他教程.

PHP是一个单独的脚本:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

function sendMsg($id, $msg) {
  echo "id: $id" . PHP_EOL;
  echo "data: $msg" . PHP_EOL;
  echo PHP_EOL;
  ob_flush();
  flush();
}

$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
?>
Run Code Online (Sandbox Code Playgroud)

并且JavaScript看起来像这样(在身体负载上运行):

function init() {

    var source;
    if (!!window.EventSource) {
        source = new EventSource('events.php');
        source.addEventListener('message', function(e) {
            document.getElementById('output').innerHTML += e.data + '<br />';
        }, false);
        source.addEventListener('open', function(e) {
            document.getElementById('output').innerHTML += 'connection opened<br />';
        }, false);
        source.addEventListener('error', function(e) {
            document.getElementById('output').innerHTML += 'error<br />';
        }, false);
    }
    else {
        alert("Browser doesn't support Server-Sent Events");
    }
}
Run Code Online (Sandbox Code Playgroud)

我搜索了一下但找不到相关信息

  1. 如果Apache需要任何特殊配置来支持服务器发送的事件,并且
  2. 如何通过这种设置从服务器启动推送(例如,我可以简单地从CLI执行PHP脚本以推送已连接的浏览器吗?)

如果我在Chrome中运行这个JS(16.0.912.77),它会打开连接,接收时间,然后是错误(错误对象中没有有用信息),然后在3秒内重新连接并完成相同的过程.在Firefox(10.0)中,我得到了相同的行为.

编辑1:我认为这个问题可能与我使用的服务器有关,所以我在一个vanilla XAMPP安装上测试了同样的错误.基本服务器配置是否能够在没有修改/额外配置的情况下处理此问题?

编辑2:以下是浏览器输出的示例:

connection opened
server time: 01:47:20
error
connection opened
server time: 01:47:23
error
connection opened
server time: 01:47:26
error
Run Code Online (Sandbox Code Playgroud)

谁能告诉我哪里出错了?我看到的教程使它看起来像SSE非常简单.对我上面两个编号问题的任何答案也会非常有帮助.

谢谢.

Fai*_*ern 21

问题是你的PHP.

使用php脚本的编写方式,每次执行只发送一条消息.如果你直接访问php文件,那就是它的工作方式,如果你使用EventSource访问该文件,那就是它的工作原理.所以为了让你的php脚本发送多条消息,你需要一个循环.

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

function sendMsg($id, $msg) {
  echo "id: $id" . PHP_EOL;
  echo "data: $msg" . PHP_EOL;
  echo PHP_EOL;
  ob_flush();
  flush();
}
while(true) {
  $serverTime = time();
  sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
  sleep(1);
}
?>
Run Code Online (Sandbox Code Playgroud)

我已经更改了您的代码,以包含一个无限循环,在每个消息发送后等待1秒(遵循此处的示例:使用服务器发送的事件).

这种类型的循环是我目前正在使用的,它消除了恒定的连接丢弃并每3秒重新连接一次.然而(我只在chrome中测试过这个),现在连接只保持活动30秒.我将继续弄清楚为什么会出现这种情况,我会在找到解决方案时发布解决方案,但在此之前,这至少应该让您更接近目标.

希望有所帮助,

编辑:

为了使用php保持连接打开很长时间,你需要设置max_execution_time(感谢tomfumb).这可以通过至少三种方式实现:

  1. 如果您可以更改php.ini,请更改"max_execution_time"的值.这将允许您指定的所有脚本运行.
  2. 在您希望运行很长时间的脚本中,使用函数ini_set(key,value),其中key是'max_execution_time',value是您希望脚本运行的时间(以秒为单位).
  3. 在您希望运行很长时间的脚本中,使用函数set_time_limit(n),其中n是您希望脚本运行的秒数.