3

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

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

我没有的(我希望这个链接能给我的)是一个如何触发对我的应用程序更有用的 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 的 Net 面板中看到的那样,它似乎有效,但我的事件没有被处理(我意识到上面的脚本将再次运行该循环,我只想在连接的浏览器中处理我的事件,然后我将删除/清理)。

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

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

4

1 回答 1

3

您的方法中有几个问题:

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

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

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

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

于 2012-03-10T22:42:49.057 回答