Skip to content

Installation

Requirements

Before installing the package, verify:

  • PHP 8.2 or newer;
  • the PHP JSON extension;
  • CodeIgniter 4.7 or newer;
  • Redis for the Redis adapter, or a Mercure Hub for the Mercure adapter;
  • Composer package discovery enabled in the application.

The Redis adapter speaks RESP2 over PHP stream sockets. No PhpRedis extension or third-party Redis client is needed.

The Mercure publisher uses CodeIgniter's CURLRequest client and therefore requires ext-curl. See Mercure Hub when using that adapter.

Install with Composer

composer require maniaba/codeigniter4-sse

CodeIgniter discovers the package namespace, services, routes, and Spark commands through Composer.

Publish the application config and browser module:

php spark sse:install

The command creates:

app/Config/Sse.php
public/vendor/codeigniter4-sse/sse-client.js
public/vendor/codeigniter4-sse/sse-client.d.ts
public/vendor/codeigniter4-sse/adapters/*.js
public/vendor/codeigniter4-sse/adapters/*.d.ts

Existing files are skipped. Use --force only when they should be replaced, or --no-assets to publish only the PHP config:

php spark sse:install --no-assets

If the application has disabled Composer discovery in Config\Modules, enable it before using the automatic package integration:

public $discoverInComposer = true;

Applications using Config\Modules::$composerPackages['only'] must include the Composer package name:

public $composerPackages = [
    'only' => [
        'maniaba/codeigniter4-sse',
    ],
];

Run the following commands to confirm discovery:

php spark routes
php spark list

The route list should contain the SSE endpoint, and the command list should contain sse:health-check.

Configure Redis

For local development:

public string $channelPrefix = 'app:sse:';

public array $redis = [
    'host'     => '127.0.0.1',
    'port'     => 6379,
    'database' => 0,
];

Then check connectivity:

redis-cli ping
php spark sse:health-check

The health check validates the package configuration and opens a Redis connection without starting an HTTP stream.

Redis Pub/Sub channels are not isolated by selected database. Always use a distinct channelPrefix for each application and test suite.

Configure Mercure

Mercure is an alternative to Redis plus the PHP stream endpoint. It keeps sse()->publish(...), but browsers hold their EventSource connection directly against the Hub:

public string $broker = 'mercure';

Configure Hub URLs, publisher/subscriber keys, topic prefix, and cookie attributes before publishing. The complete development and production setup is documented under Mercure Hub.

Install the browser client

Applications with a frontend build can install the browser client from npm:

npm install @maniaba/codeigniter4-sse-browser

Then import it from the package:

import { SseClient } from '@maniaba/codeigniter4-sse-browser';

The package includes TypeScript declarations.

Without npm, the installer publishes the source ES module from:

vendor/maniaba/codeigniter4-sse/resources/js/sse-client.js
vendor/maniaba/codeigniter4-sse/resources/js/adapters/

The default public import is:

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

Alternatively, copy the source into an existing asset pipeline:

cp vendor/maniaba/codeigniter4-sse/resources/js/sse-client.js \
    public/assets/sse-client.js
cp vendor/maniaba/codeigniter4-sse/resources/js/sse-client.d.ts \
    public/assets/sse-client.d.ts
cp -R vendor/maniaba/codeigniter4-sse/resources/js/adapters \
    public/assets/adapters

Then import it:

import { SseClient } from '/assets/sse-client.js';

Do not serve the entire vendor/ directory from the web root.

Verify the HTTP stream

The default authorizer permits public.* channels, so a public channel is useful for the first smoke test:

curl -N \
    -H 'Accept: text/event-stream' \
    'http://localhost:8080/sse?channels=public.demo'

In a second terminal, publish a test event from application code or a small Spark command:

sse()->publish(
    'public.demo',
    'demo.updated',
    ['ready' => true],
);

curl should receive an SSE frame without waiting for the connection to end.

Production checklist

Before exposing the endpoint:

  1. implement private-channel authorization;
  2. configure the authenticated user resolver;
  3. apply application authentication plus reconnect rate/concurrency filters to private stream routes;
  4. use TLS for remote Redis connections;
  5. set an application-specific Redis channel prefix;
  6. disable proxy and FastCGI buffering for the SSE route;
  7. size PHP-FPM for the expected number of concurrent streams;
  8. keep finite connection lifetime and heartbeats enabled.

See Streaming and deployment.