PHPackages                             maniaba/codeigniter4-sse - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. maniaba/codeigniter4-sse

ActiveLibrary[Caching](/categories/caching)

maniaba/codeigniter4-sse
========================

Redis and Mercure Server-Sent Events for CodeIgniter 4

v1.0.0-rc2(today)02↑2900%MITPHPPHP ^8.2CI passing

Since Aug 1Pushed todayCompare

[ Source](https://github.com/maniaba/codeigniter4-sse)[ Packagist](https://packagist.org/packages/maniaba/codeigniter4-sse)[ Docs](https://github.com/maniaba/codeigniter4-sse)[ RSS](/packages/maniaba-codeigniter4-sse/feed)WikiDiscussions develop Synced today

READMEChangelog (2)Dependencies (6)Versions (4)Used By (0)

CodeIgniter SSE
===============

[](#codeigniter-sse)

[![PHPUnit](https://github.com/maniaba/codeigniter4-sse/actions/workflows/phpunit.yml/badge.svg)](https://github.com/maniaba/codeigniter4-sse/actions/workflows/phpunit.yml)[![PHPStan](https://github.com/maniaba/codeigniter4-sse/actions/workflows/phpstan.yml/badge.svg)](https://github.com/maniaba/codeigniter4-sse/actions/workflows/phpstan.yml)[![Docs](https://github.com/maniaba/codeigniter4-sse/actions/workflows/docs.yml/badge.svg)](https://github.com/maniaba/codeigniter4-sse/actions/workflows/docs.yml)[![Coverage Status](https://camo.githubusercontent.com/8df92130dd2c4611856fb4613d566f4c51b44592b30009ec3f4d92f1855ac9ed/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6d616e696162612f636f646569676e69746572342d7373652f62616467652e7376673f6272616e63683d646576656c6f70)](https://coveralls.io/github/maniaba/codeigniter4-sse?branch=develop)

[![PHP](https://camo.githubusercontent.com/c2588b5670f2c910b8cc849ace22a22efda8956b7c2f797d11d2096bbfc7b1f5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3737374242342e737667)](https://www.php.net/)[![CodeIgniter](https://camo.githubusercontent.com/5870e49c9550e3b8bf0ae591d5d3c956809098b4d52f8d257a9d4d045b193887/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f646549676e697465722d342e372532422d4444343831342e737667)](https://codeigniter.com/)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE.md)

CodeIgniter SSE is a lightweight, powerful Server-Sent Events library for CodeIgniter 4. It provides a clean, framework-native API for building real-time features with one-way event streams over HTTP.

Use it for notifications, progress updates, activity feeds, logs, live dashboards, and other event-driven UI updates. Application code publishes semantic events through one CI4 service, while the selected broker adapter handles Redis or Mercure delivery, browser streaming, and reconnect behavior.

```
                         ┌─ Redis Pub/Sub ── PHP SSE response ─┐
CodeIgniter application ┤                                    ├─ Browser
    sse()->publish()     └─ Mercure Hub ──────────────────────┘

```

The public API stays independent of the transport. Start with Redis for simple deployments, switch to Mercure when long-lived browser connections should move out of PHP, and keep the same `sse()->publish(...)` application code.

Requirements
------------

[](#requirements)

- PHP 8.2 or newer
- CodeIgniter 4.7 or newer
- Redis server for the Redis adapter, or a Mercure Hub
- `ext-curl` when using Mercure

Installation
------------

[](#installation)

Install the package:

```
composer require maniaba/codeigniter4-sse
php spark sse:install
```

Ensure that Redis is reachable:

```
redis-cli ping
php spark sse:health-check
```

The package speaks RESP2 over PHP stream sockets. It does not require PhpRedis, Predis, or another Redis client package. The PHP JSON extension is required.

Package routes, services, and Spark commands are discovered through CodeIgniter's Composer package discovery. See [Installation](docs/installation.md) when discovery is restricted in your application.

Quick start
-----------

[](#quick-start)

Publish an event from a controller, domain service, listener, command, or queue worker:

```
sse()->publish(
    "users.{$userId}",
    'notification.created',
    [
        'title'   => 'Order paid',
        'orderId' => 918,
    ],
);
```

Open the stream for one or more logical channels:

```
GET /sse?channels=users.42,orders.918
Accept: text/event-stream
```

Use the included framework-independent ES module:

```
import {
    RedisSseAdapter,
    SseClient,
} from '/vendor/codeigniter4-sse/sse-client.js';

const live = new SseClient({
    endpoint: '/sse',
    adapter: new RedisSseAdapter(),
    channels: [`users.${currentUserId}`],
    withCredentials: true,
});

live.on('notification.created', ({ data }) => {
    showToast(data.title);
    refreshOrder(data.orderId);
});

live.on('status', ({ status }) => {
    document.documentElement.dataset.liveStatus = status;
});

live.connect();
```

`SseClient` opens EventSource through the selected frontend adapter. When the server broker changes, update the adapter class in the browser client.

The browser's native `EventSource` automatically reconnects when a connection ends. With Redis, the package intentionally limits the PHP stream lifetime. With Mercure, the browser streams directly from the Hub.

Channel security
----------------

[](#channel-security)

The built-in authorization policy permits only channels under `public.*`. Every user, tenant, order, project, or other private channel is denied until the application provides a `ChannelAuthorizerInterface` implementation.

```
namespace App\Sse;

use Maniaba\CodeIgniterSse\Contracts\ChannelAuthorizerInterface;

final class ChannelAuthorizer implements ChannelAuthorizerInterface
{
    public function authorize(?object $user, string $channel): bool
    {
        if (str_starts_with($channel, 'public.')) {
            return true;
        }

        if (
            $user !== null
            && preg_match('/^users\.(\d+)$/', $channel, $matches) === 1
        ) {
            return (string) $user->id === $matches[1];
        }

        return false;
    }
}
```

Register a matching `UserResolverInterface` when the application uses session, Shield, JWT, or another authentication system. Channel names supplied by the browser are logical names; clients never receive or control the internal Redis prefix. In production, private SSE routes should also use application authentication and per-user rate/concurrency filters to control open streams and reconnect churn; filters do not replace per-channel authorization.

See [Channels and authorization](docs/channels-and-authorization.md) for the complete setup.

Configuration
-------------

[](#configuration)

Create `app/Config/Sse.php` when defaults need to be changed:

```
