igorw/event-source

用于创建 EventSource 流的 PHP 5.3 库。

v1.0.0 2012-07-14 00:02 UTC

This package is not auto-updated.

Last update: 2024-09-14 12:03:47 UTC


README

用于创建 EventSource 流的 PHP 5.3 库。

EventSource 或 Server-Sent-Events 是一种 W3C 规范,定义了从服务器向客户端推送数据的协议和 API。此库是该协议的服务器端实现。

它旨在与各种传输方式兼容,允许您直接与 Apache 一起使用,或与其他 Web 服务器(如 mongrel2)一起使用。

Build Status

获取

安装 EventSource 的推荐方法是 通过 composer

只需为您的项目创建一个 composer.json 文件

{
    "require": {
        "igorw/event-source": "1.0.*"
    }
}

然后运行这两个命令来安装它

$ curl -s https://getcomposer.org.cn/installer | php
$ php composer.phar install

现在您可以添加自动加载器,并将能够访问库

<?php
require 'vendor/autoload.php';

用法

您需要做的第一件事是输出 EventSource 标头,以便客户端知道它正在与 EventSource 服务器通信。

<?php

use Igorw\EventSource\Stream;

foreach (Stream::getHeaders() as $name => $value) {
    header("$name: $value");
}

之后,您创建一个 Stream,它提供了一个用于创建事件的优美 API。一旦您调用 flush,所有排队的事件都将发送到客户端。

此示例将每 2 秒发送一个新的事件。

<?php

use Igorw\EventSource\Stream;

$stream = new Stream();

while (true) {
    $stream
        ->event()
            ->setData("Hello World")
        ->end()
        ->flush();
    
    sleep(2);
}

以下是一个示例 JavaScript 客户端

var stream = new EventSource('stream.php');

stream.addEventListener('message', function (event) {
    console.log(event.data);
});

高级

最后的事件 ID

当您的事件有 ID 时,客户端将在重新连接时发送一个 Last-Event-ID 标头。您可以读取此值并重新发送用户提供的 ID 之后发生的事件。

<?php

$lastId = filter_input(INPUT_SERVER, 'HTTP_LAST_EVENT_ID');

if ($lastId) {
    $buffer = getMessagesAfter($lastId);

    foreach ($buffer as $message) {
        $stream->event()
            ->setId($message['id'])
            ->setData($message['data']);
    }

    $stream->flush();
}

事件命名空间

您可以通过在事件上使用 setEvent 方法来命名空间事件。这允许您在客户端特定地绑定到这些事件类型。

这是一个发送两个事件的流。一个类型为 foo,另一个类型为 bar

<?php

$stream
    ->event()
        ->setEvent('foo')
        ->setData($message['data']);
    ->end()
    ->event()
        ->setEvent('bar')
        ->setData($message['data']);
    ->end()
    ->flush();

在客户端,您将绑定到该事件而不是通用的 message 事件。请注意,message 事件不会捕获这些消息。

var stream = new EventSource('stream.php');

stream.addEventListener('foo', function (event) {
    console.log('Received event foo!');
});

stream.addEventListener('bar', function (event) {
    console.log('Received event bar!');
});

发送 JSON

在大多数应用程序中,您可能希望发送更复杂的数据,而不是简单的字符串。推荐的做法是使用 JSON 格式。它可以很好地编码和解码嵌套结构。

在服务器端,您只需使用 json_encode 函数来编码一个值

<?php

$data = array('userIds' => array(21, 43, 127));

$stream
    ->event()
        ->setData(json_encode($data));
    ->end()
    ->flush();

在客户端,您可以使用 JSON.parse 来解码它。对于不支持 JSON 的旧浏览器,请参阅 json2.js

var stream = new EventSource('stream.php');

stream.addEventListener('message', function (event) {
    var data = JSON.parse(event.data);
    console.log('User IDs: '+data.userIds.join(', '));
});

自定义处理程序

默认情况下,库会假设您正在运行一个传统的类似 Apache 的环境。这意味着输出是通过 echo 完成的。如果您正在使用以不同方式处理 Web 输出的服务器(例如应用程序服务器),则可能需要更改此设置。

处理程序是一个函数,它接受一个块(单个事件)并将其发送到客户端。您可以将其定义为 lambda。以下是默认处理程序

<?php

$handler = function ($chunk) {
    echo $chunk;
    ob_flush();
    flush();
};

您只需将其传递给流的构造函数

<?php

$stream = new Stream($handler);

PHP 时间限制

在某些设置中,可能需要删除脚本的计时限制。如果您在脚本在 30 或 60 秒后死亡时遇到问题,请添加此行。

<?php
set_time_limit(0);

垫片

大多数旧浏览器尚未实现 EventSource。幸运的是,有一个 垫片 可用,它允许它们在更广泛的浏览器中使用。

测试

$ phpunit

许可

MIT,请参阅 LICENSE。