全部的

HTML5 Rocks提供了一个关于服务器发送事件(SSE)的入门教程:

http://www.html5rocks.com/en/tutorials/eventsource/basics/

但是,我不理解一个重要的概念——是什么触发了服务器上导致消息发送的事件?

换句话说,在HTML5示例中,服务器仅发送时间戳once:

<?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风格的"墙"或股票报价器,其中服务器会在每次某个数据发生更改时向客户端"推送"一条新消息,那么这是如何工作的呢?

换句话说...Does the PHP script have a loop that runs continuously, checking for a change in the data, then sending a message every time it finds one? If so - how do you know when to end that process?

或者-PHP脚本是否只是发送消息,然后结束(就像HTML5Rock示例中的情况一样)?如果是这样的话-您如何获得持续的更新?浏览器只是定期轮询PHP页面吗?如果是,那怎么会是"服务器发送的事件"呢?这与用JavaScript编写setInterval函数(使用Ajax定期调用PHP页面)有何不同?

抱歉,这可能是一个非常天真的问题.但我所能找到的例子中没有一个能清楚地说明这一点.

[更新]

我认为我的问题措辞不好,所以这里有一些澄清.

假设我有一个网页,可以显示苹果股票的最新价格.

当用户第一次打开页面时,页面会使用我的"流"的URL创建一个事件源.

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的实例呢?

我天真的感觉是,如果是这样的话,PHPisn't是一种适合这种服务器的技术.但到目前为止,我看到的所有演示都表明PHP可以胜任这项工作,这就是为什么我如此困惑的原因...

推荐答案

"…确实"流.php"只要客户端"连接",就保持开放状态"

是的,你的伪代码是一个合理的方法.

"您如何知道何时可以结束stream.php的实例?"

在最典型的情况下,当用户离开您的站点时,就会发生这种情况.(Apache识别关闭的套接字,并杀死PHP实例.)从服务器端关闭套接字的主要时间是,如果知道暂时没有数据;你向客户发送的最后一条信息是告诉他们在某个时间回来.例如,在你的股票流媒体 case 中,你可以在晚上8点关闭连接,并告诉客户8小时后回来(假设纳斯达克在上午4点到晚上8点开放报价).星期五晚上你告诉他们星期一早上回来.(我即将出版一本关于苏格兰和南方能源公司的书,并专门介绍了几个章节.)

"……如果是这样的话,PHP不适合这种技术

嗯,人们争辩说PHP不是一种适合于普通网站的技术,他们是对的:如果用C++取代整个LAMP堆栈,那么可以使用更少的内存和CPU周期来完成这项工作.然而,尽管如此,PHP仍然可以很好地支持大多数站点.它是一种非常高效的网络工作语言,这要归功于熟悉的类似C的语法和如此多的库的结合,这对管理者来说是一种令人欣慰的语言,因为有大量的PHP程序员可供雇佣,大量的书籍和其他资源,以及一些大型的用例(例如Facebook和Wikipedia).这些基本上与您 Select PHP作为流媒体技术的原因相同.

典型的设置不是每个PHP实例一个到NASDAQ的连接.取而代之的是,您将拥有另一个与纳斯达克的单一连接的进程,或者集群中的每台机器与纳斯达克的单一连接.然后将价格推送到SQL/NoSQL服务器或共享内存中.然后PHP只轮询共享内存(或数据库),并将数据推出.或者,使用一个数据收集服务器,每个PHP实例打开一个到该服务器的套接字连接.数据收集服务器在接收到每个PHP客户机时,会将更新推送到每个PHP客户机,然后这些客户机又会将数据推送到自己的客户机.

使用Apache+PHP进行流媒体处理的主要可伸缩性问题是每个Apache进程的内存.当您达到硬件的内存限制时,做出业务决策,将另一台机器添加到集群中,或者将Apache从循环中删除,并编写一个专用HTTP服务器.后者可以在PHP中完成,这样所有现有知识和代码都可以重用,或者可以用另一种语言重写整个应用程序.我的纯开发者会在C++中编写一个专用的、简化的HTTP服务器.我的经理会再加一个盒子.

Php相关问答推荐

仅在WooCommerce管理订单视图上显示订单项自定义元数据

如何在函数中定位WooCommerce产品循环

在WooCommerce中添加基于类别的固定费用

WooCommerce数量减号和加号图标未显示

EBay Inventory API createOrReplaceInventoryItem出错

在WooCommerce中的本地收件发货方式下添加一个 Select 字段

使用php ZipArhive类将Zip压缩文件分成多个部分

如何使用MS Graph PHP SDK V2下载文件

限制某些产品只能在WooCommerce的特定邮政编码/邮政编码范围内发货

在Laravel中从动态嵌套数组中获取值

Laravel withOnly不限制查询

Wordpress,配置一周第一天选项

WooCommerce:如果购物车中已存在产品,则增加购物车商品数量

按日期向 WooCommerce 中的我的帐户订单添加过滤器

通过ajax发送数据到下拉列表未完全设置为所选

正则表达式将文本替换为标签 html 以字符开头

如何获得没有运输等级的产品

在 WordPress 中使用 $wpdb 运行 MySQL 事务是否安全?

判断类别是否存在 Shopware 6

Symfony 自定义注销