【发布时间】:2013-01-11 23:03:33
【问题描述】:
全部,
HTML5 Rocks 有一个关于服务器发送事件 (SSE) 的不错的初学者教程:
http://www.html5rocks.com/en/tutorials/eventsource/basics/
但是,我不明白一个重要的概念 - 是什么触发了服务器上导致发送消息的事件?
换句话说 - 在 HTML5 示例中 - 服务器只是发送一个时间戳一次:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.
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()));
如果我正在构建一个实际示例 - 例如,Facebook 风格的“墙”或股票行情,其中服务器会在每次某些数据更改时向客户端“推送”一条新消息,如何那行吗?
换句话说... PHP 脚本是否有一个循环持续运行,检查数据的变化,然后在每次找到时发送一条消息?如果是这样 - 你怎么知道什么时候结束这个过程?
或者 - PHP 脚本是否只是发送消息,然后结束(在 HTML5Rocks 示例中似乎就是这种情况)?如果是这样 - 您如何获得持续更新?浏览器是否只是定期轮询 PHP 页面?如果是这样 - 那是一个“服务器发送的事件”吗?这与在 JavaScript 中使用 AJAX 定期调用 PHP 页面的 setInterval 函数有何不同?
抱歉 - 这可能是一个非常幼稚的问题。但是我找到的例子都没有说明这一点。
[更新]
我认为我的问题措辞不当,所以在这里澄清一下。
假设我有一个网页应该显示 Apple 股票的最新价格。
当用户第一次打开页面时,页面会使用我的“流”的 URL 创建一个 EventSource。
var source = new EventSource('stream.php');
我的问题是——“stream.php”应该如何工作?
像这样? (伪代码):
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.
function sendMsg($msg) {
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
flush();
}
while (some condition) {
// check whether Apple's stock price has changed
// e.g., by querying a database, or calling a web service
// if it HAS changed, sendMsg with new price to client
// otherwise, do nothing (until next loop)
sleep (n) // wait n seconds until checking again
}
?>
换句话说 - 只要客户端“连接”到它,“stream.php”就保持打开状态吗?
如果是这样 - 这是否意味着运行 stream.php 的线程数与并发用户数一样多?如果是这样 - 这是远程可行的,还是构建应用程序的适当方式?你怎么知道什么时候可以ENDstream.php 的实例?
我的天真印象是,如果是这样的话,PHP 不是适合这种服务器的技术。但是到目前为止我看到的所有演示都暗示 PHP 对此很好,这就是为什么我很困惑...
【问题讨论】:
-
这是开发人员必须自己编写代码的部分。获取数据的方法是通过 websockets/长轮询等。但是诀窍是 what 触发事件。就个人而言,我尝试了几种方法,其中一种我喜欢的方法(但它不是那故障安全的)是让 MySQL 每次在特定表中插入某些内容时触发一个控制台程序.控制台程序将接收有关更改/插入记录的信息,并通过 WebSockets 向相应用户发送通知。基本上我有一个 PHP 守护进程等待发送消息。
-
这个有一个问题,IE 不支持 SSE :-/ 我也会读这个 prodigyproductionsllc.com/articles/programming/javascript/… 我认为他正在使用端口来避免太多孩子的问题,但总体看起来像他的建议避免 SSE。看起来麻烦多于它的价值,IMO。
-
IE11或Android浏览器目前不支持caniuse.com/eventsource
-
如果有人需要sse php代码:github.com/shahzadthathal/server-sent-events-php-example
-
我也有同样的问题,我想我深深理解你所说的什么触发了服务器上的事件...。当您创建
EventSource('stream.php')的对象时,客户端会打开与stream.php的连接,这就像通过ajax 调用它一样。 此 连接会触发您的服务器端代码并保持连接打开,只要您的服务器端代码有话要说。然后连接关闭,经过短暂的延迟(我认为在 chrome 中为 3 秒)客户端重新打开连接,再次触发您的stream.php文件。