Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
服务器发送事件和php-什么触发服务器上的事件?_Php_Server Sent Events - Fatal编程技术网

服务器发送事件和php-什么触发服务器上的事件?

服务器发送事件和php-什么触发服务器上的事件?,php,server-sent-events,Php,Server Sent Events,全部, HTML5 Rocks提供了一个关于服务器发送事件(SSE)的入门教程: 但是,我不理解一个重要的概念——是什么触发了服务器上导致发送消息的事件 换句话说,在HTML5示例中,服务器只发送一次时间戳: 我的问题是,“stream.php”应该如何工作 像这样?(伪代码): 这实际上是一个有关应用程序的结构性问题。实时事件是您希望从一开始就考虑的事情,因此您可以围绕它设计应用程序。如果您编写了一个应用程序,它只运行一组使用字符串查询的随机mysql(i)\u query方法,并且没有通过

全部,

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

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

换句话说,在HTML5示例中,服务器只发送一次时间戳:

我的问题是,“stream.php”应该如何工作

像这样?(伪代码):


这实际上是一个有关应用程序的结构性问题。实时事件是您希望从一开始就考虑的事情,因此您可以围绕它设计应用程序。如果您编写了一个应用程序,它只运行一组使用字符串查询的随机
mysql(i)\u query
方法,并且没有通过任何类型的中介,那么很多时候您将别无选择,只能重写大部分应用程序,或者执行持续的服务器端轮询

但是,如果您将实体作为对象进行管理,并通过某种中介类将其传递,则可以挂接到该过程中。看看这个例子:

<?php
class MyQueryManager {
    public function find($myObject, $objectId) {
        // Issue a select query against the database to get this object
    }

    public function save($myObject) {
        // Issue a query that saves the object to the database
        // Fire a new "save" event for the type of object passed to this method
    }

    public function delete($myObject) {
        // Fire a "delete" event for the type of object
    }
}

服务器发送事件用于从服务器端到客户端的实时更新。在第一个示例中,没有保持与服务器的连接,客户端每3秒钟尝试再次连接一次,使服务器发送的事件与ajax轮询没有区别

因此,为了保持连接,您需要将代码包装在一个循环中,并不断检查更新

PHP是基于线程的,更多的连接用户将使服务器资源耗尽。这可以通过控制脚本执行时间来解决,并在脚本执行时间超过一定时间(即10分钟)时结束脚本。
EventSource
API将自动重新连接,因此延迟在可接受的范围内

另外,请查看我的,您可以了解有关如何在PHP中执行服务器发送事件的更多信息,并使其更易于编码

“…只要客户端处于“连接”状态,“stream.php”是否保持打开状态?” “对吗?”

是的,您的伪代码是一种合理的方法

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

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

“…如果是这样,PHP就不适合这种技术 但是到目前为止我看到的所有演示都暗示PHP是 这很好,这就是为什么我如此困惑的原因……”

人们认为PHP不是一个适合普通网站的技术,他们是正确的:如果你用C++替换整个LCD堆栈,你可以做的内存和CPU周期要少得多。然而,尽管如此,PHP还是很好地支持了大多数网站。它是一种非常高效的web工作语言,因为它结合了熟悉的C类语法和许多库,对于经理来说是一种令人欣慰的语言,因为有大量的PHP程序员需要雇佣,有大量的书籍和其他资源,还有一些大的使用案例(如Facebook和Wikipedia)。这些基本上与您选择PHP作为流媒体技术的原因相同

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


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

我注意到sse techink每隔两个延迟就向客户端发送一次数据(类似于从客户端页面反转池数据techink,例如Ajax池数据)。因此,为了克服这个问题,我在sseServer.php页面上做了如下操作:

<?php
        session_start();
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache'); // recommended to prevent caching of event data
        require 'sse.php';
        if ($_POST['message'] != ""){
                $_SESSION['message'] = $_POST['message'];
                $_SESSION['serverTime'] = time();
        }
        sendMsg($_SESSION['serverTime'], $_SESSION['message'] );
?>
在以下行:
$.notify(“请刷新”+event.data,“info”)
你能处理这条信息吗

对于我的案例,我曾经发送jQuery通知

您可以使用POSIX管道或DB表通过POST传递“消息”,因为sseServer.php执行类似于“无限循环”的操作

我当时的问题是,上面的代码并没有将“消息”发送给所有客户端,而只是发送给这对客户端(调用sseServer.php的客户端对每对客户端都是独立的),因此我将更改technik并从我想要触发“消息”的页面更新到DB然后sseServer.php通过POST获取消息,它将从DB表中获取消息


我希望我能得到帮助

基本上,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
    }
?>
<?php
class MyQueryManager {
    public function find($myObject, $objectId) {
        // Issue a select query against the database to get this object
    }

    public function save($myObject) {
        // Issue a query that saves the object to the database
        // Fire a new "save" event for the type of object passed to this method
    }

    public function delete($myObject) {
        // Fire a "delete" event for the type of object
    }
}
<?php
$someObject = $queryManager->find("MyObjectName", 1);
$someObject->setDateTimeUpdated(time());
$queryManager->save($someObject);
<?php
        session_start();
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache'); // recommended to prevent caching of event data
        require 'sse.php';
        if ($_POST['message'] != ""){
                $_SESSION['message'] = $_POST['message'];
                $_SESSION['serverTime'] = time();
        }
        sendMsg($_SESSION['serverTime'], $_SESSION['message'] );
?>
<?php
function sendMsg($id, $msg) {
  echo "id: $id" . PHP_EOL;
  echo "data: $msg" . PHP_EOL;
  echo PHP_EOL;
  ob_flush();
  flush();
}
?>
if(typeof(EventSource)!=="undefined"){
        var source=new EventSource("sseServer.php");
        source.onmessage=function(event)
        if ((timeStamp!=event.lastEventId) && (timeStamp!=0)){
                /* this is initialization */
                timeStamp=event.lastEventId;
                $.notify("Please refresh "+event.data, "info");
        } else {
                if (timeStamp==0){
                         timeStamp=event.lastEventId;
                }
        } /* fi */

} else {
        document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
} /* fi */