php - 如何触发 EventSource SSE 事件?

标签 php javascript events server-push server-sent-events

我最近发现了 EventSource,YUI3 有一个 Gallery 模块来规范化和回退行为,这就是我在示例中选择使用的模块,因为我已经在使用该框架了。

因此,我进行了相当多的搜索,阅读了许多博客、帖子和示例,所有这些都显示了几乎相同的内容:如何设置基本 SSE 事件。我现在有 6 个触发打开/消息/错误/关闭事件的示例。

我没有的(我希望 this link 会给我的)是如何触发对我的应用程序更有用的 SSE 事件的示例,我正在尝试一个名为“更新”的事件.

这是我的基本测试页面:http://codefinger.co.nz/public/yui/eventsource/test.php (它也可能是一个 html 文件,这里还没有 php 代码)

这是 EventSource 构造函数中的“message.php”:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.

/**
 * Constructs the SSE data format and flushes that data to the client.
 *
 * @param string $id Timestamp/id of this connection.
 * @param string $msg Line of text that should be transmitted.
 */
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(10);
}

// I was hoping calling this file with a param might allow me to fire an event,
// which it does dutifully, but no browsers register the 'data : update' - though
// I do see the response in Firebug.
if( $_REQUEST['cmd'] ){
    sendMsg($serverTime, $_REQUEST['cmd'] );
}
?>

从上面的实例中,您可以看到我尝试使用 YUI 的 io 模块发送一个带有参数的请求,以便在我单击“更新”按钮时触发我的“更新”事件。它似乎有效,正如您在 Firebug 的网络面板中看到的那样,但我的事件没有得到处理(我意识到上面的脚本将再次运行该循环,我只想在连接的浏览器中处理我的事件,然后我将删除/清理)。

我这部分做错了吗?还是我做错了更根本的事情?我正在尝试推送事件以响应我的 UI 状态变化。

This SO question似乎接近了,@tomfumb 评论说他的下一个问题将是“如何在建立初始连接后向客户端发送新事件 - 现在我看到 PHP 永远不会停止执行。”但我肯定只会在事件发生时发送事件……而不是连续发送……

最佳答案

您的方法存在几个问题:

  1. 由于向客户端发送事件数据的无限循环,读取 cmd 参数的服务器端代码无法访问。
  2. 您正在尝试从客户端向服务器发送一个事件。它在规范名称 - Server-Sent Events - 服务器是发送者,客户端是事件的接收者。你在这里有选择:
    1. 为名为 Web Sockets 的工作使用适当的规范这是一个双向通信API
    2. 编写使所需类型的通信成为可能的逻辑

如果您选择继续使用 SSE API,我会看到两种可能的情况

  1. 重复使用相同的事件源连接并在服务器上存储一个连接池。当用户使用更新命令发送后续 XMLHttpRequest 时,从池中获取此访问者创建的 EventSource 连接,并发送指定自定义事件类型的响应,默认类型为消息。重要的是要避免进入会与客户端建立另一个 EventSource 连接的无限循环,但客户端不会处理它,因为他使用 XMLHttpRequest 而不是 EventSource 发出请求。
  2. 使用 EventSource 发出所有请求。在发出新的 EventSource 请求之前,关闭前一个 - 您可以从客户端或服务器执行此操作。在服务器上检查参数,然后将数据发送给客户端。

您还可以将 XMLHttpRequest 与(长)轮询一起使用,从而避免使用 EventSource。由于您示例的简单性,我看不出混合这两种请求的理由。

关于php - 如何触发 EventSource SSE 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9565290/

相关文章:

php - SimpleXMLElement::__construct(): 实体: 第 68 行: 解析器错误

php - Nginx, PHP, Apache, MySQL - 当加载大量页面时所有 php 请求都在等待(仅针对请求客户端)

javascript - 在 Laravel 中将 javascript 数组转换为 php 数组

javascript - 我想用点击事件创建元素,但有问题

c# - 当事件触发时执行类上的 void 方法的单元测试

php - 如何获取 Laravel Controller 方法的所有可能的错误消息

javascript - 单击时播放音频

javascript - 网络音频 api : how to inspect the audio graph?

javascript - D3 xlink : "href" appends image fine on Google Chrome but not on Firefox

javascript/jquery : responding to a user clicking "ok" on an alert dialog