如何解雇EventSource SSE事件?

时间:2012-03-05 10:45:02

标签: 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模块发送请求,使用param,在我点击“更新”按钮时触发“更新”事件。它似乎工作,你可以在Firebug的Net面板中看到,但我的事件没有处理(我意识到上面的脚本将再次运行该循环,我只是想在连接的浏览器中处理我的事件,然后我将删除/清理)。

我做错了吗?还是有一些更基本的我做错了?我正在尝试推送事件以响应我的UI状态变化。

This SO question似乎已经接近了,@ tomfumb评论说他的下一个问题是“如何在初始连接完成后向客户端发送新事件 - 现在我看到PHP必须永远不会停止执行。“但当然我只会发生事件......而不是连续......

1 个答案:

答案 0 :(得分:2)

您的方法有几个问题:

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

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

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

此外,您可以将XMLHttpRequest与(长)轮询一起使用,从而避免使用EventSource。由于您的示例简单,我无法看到混合两种类型请求的理由。