hhxsv5 / php-sse
这是一个简单高效的库,通过PHP实现了HTML5的服务器端发送事件,用于从服务器实时推送事件到客户端,比Websocket简单,代替AJAX请求。
v2.0.2
2021-03-04 09:49 UTC
Requires
- php: >=5.4
Requires (Dev)
- phpunit/phpunit: ~6.0
- swoole/ide-helper: @dev
README
这是一个简单高效的库,通过PHP实现了HTML5的服务器端发送事件,用于从服务器实时推送事件到客户端,比Websocket简单,代替AJAX请求。
需求
- PHP 5.4或更高版本
通过Composer安装(packagist)
composer require "hhxsv5/php-sse:~2.0" -vvv
使用方法
运行演示
- 运行PHP web服务器
cd examples php -S 127.0.0.1:9001 -t .
- 打开url
http://127.0.0.1:9001/index.html
JavaScript演示
客户端:从服务器接收事件。
// withCredentials=true: pass the cross-domain cookies to server-side const source = new EventSource('http://127.0.0.1:9001/sse.php', {withCredentials: true}); source.addEventListener('news', function (event) { console.log(event.data); // source.close(); // disconnect stream }, false);
PHP演示
服务器:通过纯PHP发送事件。
use Hhxsv5\SSE\Event; use Hhxsv5\SSE\SSE; use Hhxsv5\SSE\StopSSEException; // PHP-FPM SSE Example: push messages to client header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); header('X-Accel-Buffering: no'); // Nginx: unbuffered responses suitable for Comet and HTTP streaming applications $callback = function () { $id = mt_rand(1, 1000); $news = [['id' => $id, 'title' => 'title ' . $id, 'content' => 'content ' . $id]]; // Get news from database or service. if (empty($news)) { return false; // Return false if no new messages } $shouldStop = false; // Stop if something happens or to clear connection, browser will retry if ($shouldStop) { throw new StopSSEException(); } return json_encode(compact('news')); // return ['event' => 'ping', 'data' => 'ping data']; // Custom event temporarily: send ping event // return ['id' => uniqid(), 'data' => json_encode(compact('news'))]; // Custom event Id }; (new SSE(new Event($callback, 'news')))->start();
Symfony和Laravel演示
服务器:通过Laravel或Symfony发送事件。
use Hhxsv5\SSE\SSE; use Hhxsv5\SSE\Event; use Hhxsv5\SSE\StopSSEException; // Action method in controller public function getNewsStream() { $response = new \Symfony\Component\HttpFoundation\StreamedResponse(); $response->headers->set('Content-Type', 'text/event-stream'); $response->headers->set('Cache-Control', 'no-cache'); $response->headers->set('Connection', 'keep-alive'); $response->headers->set('X-Accel-Buffering', 'no'); // Nginx: unbuffered responses suitable for Comet and HTTP streaming applications $response->setCallback(function () { $callback = function () { $id = mt_rand(1, 1000); $news = [['id' => $id, 'title' => 'title ' . $id, 'content' => 'content ' . $id]]; // Get news from database or service. if (empty($news)) { return false; // Return false if no new messages } $shouldStop = false; // Stop if something happens or to clear connection, browser will retry if ($shouldStop) { throw new StopSSEException(); } return json_encode(compact('news')); // return ['event' => 'ping', 'data' => 'ping data']; // Custom event temporarily: send ping event // return ['id' => uniqid(), 'data' => json_encode(compact('news'))]; // Custom event Id }; (new SSE(new Event($callback, 'news')))->start(); }); return $response; }
Swoole演示
服务器:通过Swoole协程Http服务器发送事件。安装Swoole 4.5.x:
pecl install swoole
。
use Hhxsv5\SSE\Event; use Hhxsv5\SSE\SSESwoole; use Swoole\Http\Request; use Swoole\Http\Response; use Swoole\Http\Server; use Hhxsv5\SSE\StopSSEException; // Swoole SSE Example: push messages to client $server = new Server('0.0.0.0', 5200); $server->set([ 'enable_coroutine' => true, 'max_coroutine' => 10000, // worker_num*10000 'reactor_num' => swoole_cpu_num() * 2, 'worker_num' => swoole_cpu_num() * 2, 'max_request' => 100000, 'buffer_output_size' => 4 * 1024 * 1024, // 4MB 'log_level' => SWOOLE_LOG_WARNING, 'log_file' => __DIR__ . '/swoole.log', ]); $server->on('Request', function (Request $request, Response $response) use ($server) { $response->header('Access-Control-Allow-Origin', '*'); $response->header('Content-Type', 'text/event-stream'); $response->header('Cache-Control', 'no-cache'); $response->header('Connection', 'keep-alive'); $response->header('X-Accel-Buffering', 'no'); $event = new Event(function () { $id = mt_rand(1, 1000); $news = [['id' => $id, 'title' => 'title ' . $id, 'content' => 'content ' . $id]]; // Get news from database or service. if (empty($news)) { return false; // Return false if no new messages } $shouldStop = false; // Stop if something happens or to clear connection, browser will retry if ($shouldStop) { throw new StopSSEException(); } return json_encode(compact('news')); // return ['event' => 'ping', 'data' => 'ping data']; // Custom event temporarily: send ping event // return ['id' => uniqid(), 'data' => json_encode(compact('news'))]; // Custom event Id }, 'news'); (new SSESwoole($event, $request, $response))->start(); }); $server->start();