为什么服务器发送的事件每 3 秒启动一次?

Wai*_*mal 7 javascript php server-sent-events

我是服务器发送事件的新手,所以我正在WAMP 服务器上尝试这个 W3Schools 示例。我拥有的文件是:

演示_sse.php

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

  $time = date('r');
  echo "data: The server time is: {$time}\n\n";
  flush();
?>
Run Code Online (Sandbox Code Playgroud)

索引.php

<!DOCTYPE html>
<html>
  <body>
    <h1>Getting server updates</h1>
    <div id="result"></div>
    <script>
      if(typeof(EventSource) !== "undefined") {
        var source = new EventSource("demo_sse.php");
        source.onmessage = function(event) {
          document.getElementById("result").innerHTML += event.data + "<br>";
        };
      } else {
        document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
      }
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

据我了解,时间在不断变化,因此必须每秒发送一次更新(至少)。但是,每三秒接收一次更新。这个间隔没有在 demo_sse.php 中指定,所以:

  • 为什么它每 3 秒发送一次更新?
  • 如何更改此间隔?

Iva*_*var 8

W3Schools 上的例子有点糟糕。

对于大多数 HTTP 响应/请求交换,客户端向服务器发出 HTTP 请求,服务器返回数据并完成交换。

对于 SSE(虽然它仍然使用 HTTP 协议),这有点不同。在这里,客户端向服务器发出请求,会话保持打开状态,服务器可以随时发送数据。如果会话因任何原因关闭,EventSource 将尝试重新连接,一切重新开始。

PHP 脚本中的问题是脚本在完成最后一行后结束请求/响应交换。这意味着连接已关闭,因此EventSource将尝试重新连接。(添加.onerror事件将显示每条消息后都会引发错误。)

如规范中所定义

重新连接时间,以毫秒为单位。这最初必须是用户代理定义的值,可能在几秒钟的范围内。

这就是您每三秒收到一次更新的原因。因为这是用户代理定义的值设置的。

在该行下方,您还可以看到:

除了 url 之外,这些当前未在 EventSource 对象上公开。

这意味着当前无法从 JavaScript 设置此值。

虽然可以通过retry在 SSE 消息的字段中定义它来从您的服务器设置此值。在这里,您可以以毫秒为单位定义用户代理在重新连接到服务器之前应等待的时间。如果要将其设置为一秒,则应为:

$time = date('r');
// If the connection closes, retry in 1 second
echo "retry: 1000\n";
echo "data: The server time is: {$time}\n\n";
flush();
Run Code Online (Sandbox Code Playgroud)

但是当然最好在第一条消息后不关闭连接的情况下正确实现 SSE。

一个很好的解释可以在 MDN 上找到。我建议一般使用 MDN 而不是 W3Schools。W3Schools 不是 Stack Overflow 上最受欢迎的资源,这是一个很好的例子。

  • “W3Schools 上的例子有点糟糕。” 听到这个我很震惊! (2认同)