PHPackages                             clue/reactphp-eventsource - 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. [Queues &amp; Workers](/categories/queues)
4. /
5. clue/reactphp-eventsource

ActiveLibrary[Queues &amp; Workers](/categories/queues)

clue/reactphp-eventsource
=========================

Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of ReactPHP's event-driven architecture.

v1.4.0(2mo ago)5818.5k↓42.9%13[2 issues](https://github.com/clue/reactphp-eventsource/issues)3MITPHPPHP &gt;=5.4CI passing

Since Apr 11Pushed 2mo ago6 watchersCompare

[ Source](https://github.com/clue/reactphp-eventsource)[ Packagist](https://packagist.org/packages/clue/reactphp-eventsource)[ Docs](https://github.com/clue/reactphp-eventsource)[ Fund](https://clue.engineering/support)[ GitHub Sponsors](https://github.com/clue)[ RSS](/packages/clue-reactphp-eventsource/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (5)Dependencies (10)Versions (6)Used By (3)

clue/reactphp-eventsource
=========================

[](#cluereactphp-eventsource)

[![CI status](https://github.com/clue/reactphp-eventsource/actions/workflows/ci.yml/badge.svg)](https://github.com/clue/reactphp-eventsource/actions)[![code coverage](https://camo.githubusercontent.com/2d45ae33b28ed0c5f14fdba645e579072cf437770a215524795c9eb258581b1c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6465253230636f7665726167652d3130302532352d73756363657373)](#tests)[![installs on Packagist](https://camo.githubusercontent.com/01bc30bba35f0fd2fedd63b7d674ca98c1ccc4eef36e7c56b427d18a0f7ce035/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636c75652f72656163747068702d6576656e74736f757263653f636f6c6f723d626c7565266c6162656c3d696e7374616c6c732532306f6e2532305061636b6167697374)](https://packagist.org/packages/clue/reactphp-eventsource)

Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of [ReactPHP](https://reactphp.org/)'s event-driven architecture.

**Table of contents**

- [Support us](#support-us)
- [Quickstart example](#quickstart-example)
- [Usage](#usage)
    - [EventSource](#eventsource)
        - [message event](#message-event)
        - [open event](#open-event)
        - [error event](#error-event)
        - [EventSource::$readyState](#eventsourcereadystate)
        - [EventSource::$url](#eventsourceurl)
        - [close()](#close)
    - [MessageEvent](#messageevent)
        - [MessageEvent::\_\_construct()](#messageevent__construct)
        - [MessageEvent::$data](#messageeventdata)
        - [MessageEvent::$lastEventId](#messageeventlasteventid)
        - [MessageEvent::$type](#messageeventtype)
- [Install](#install)
- [Tests](#tests)
- [License](#license)
- [More](#more)

Support us
----------

[](#support-us)

I maintain an ecosystem of open-source projects that have been downloaded hundreds of millions of times and are actively maintained and continuously improved. If you find any of these projects useful, please consider [becoming a sponsor on GitHub](https://github.com/sponsors/clue). Your support helps ensure long-term maintenance and continued development. Thank you! 🚀

Quickstart example
------------------

[](#quickstart-example)

Once [installed](#install), you can use the following code to stream messages from any Server-Sent Events (SSE) server endpoint:

```
data: {"name":"Alice","message":"Hello everybody!"}

data: {"name":"Bob","message":"Hey Alice!"}

data: {"name":"Carol","message":"Nice to see you Alice!"}

data: {"name":"Alice","message":"What a lovely chat!"}

data: {"name":"Bob","message":"All powered by ReactPHP, such an awesome piece of technology :)"}

```

```
$es = new Clue\React\EventSource\EventSource('https://example.com/stream.php');

$es->on('message', function (Clue\React\EventSource\MessageEvent $message) {
    $json = json_decode($message->data);
    echo $json->name . ': ' . $json->message . PHP_EOL;
});
```

See the [examples](examples/).

Usage
-----

[](#usage)

### EventSource

[](#eventsource)

The `EventSource` class is responsible for communication with the remote Server-Sent Events (SSE) endpoint.

The `EventSource` object works very similar to the one found in common web browsers. Unless otherwise noted, it follows the same semantics as defined under

Its constructor simply requires the URL to the remote Server-Sent Events (SSE) endpoint:

```
$es = new Clue\React\EventSource\EventSource('https://example.com/stream.php');
```

If you need custom connector settings (DNS resolution, TLS parameters, timeouts, proxy servers etc.), you can explicitly pass a custom instance of the [`ConnectorInterface`](https://github.com/reactphp/socket#connectorinterface)to the [`Browser`](https://github.com/reactphp/http#browser) instance and pass it as an additional argument to the `EventSource` like this:

```
$connector = new React\Socket\Connector([
    'dns' => '127.0.0.1',
    'tcp' => [
        'bindto' => '192.168.10.1:0'
    ],
    'tls' => [
        'verify_peer' => false,
        'verify_peer_name' => false
    ]
]);
$browser = new React\Http\Browser($connector);

$es = new Clue\React\EventSource\EventSource('https://example.com/stream.php', $browser);
```

This class takes an optional `LoopInterface|null $loop` parameter that can be used to pass the event loop instance to use for this object. You can use a `null` value here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). This value SHOULD NOT be given unless you're sure you want to explicitly use a given event loop instance.

#### message event

[](#message-event)

The `message` event will be emitted whenever an EventSource message is received.

```
$es->on('message', function (Clue\React\EventSource\MessageEvent $message) {
    // $json = json_decode($message->data);
    var_dump($message);
});
```

The EventSource stream may emit any number of messages over its lifetime. Each `message` event will receive a [`MessageEvent` object](#messageevent).

The [`MessageEvent::$data` property](#messageeventdata) can be used to access the message payload data. It is commonly used for transporting structured data such as JSON:

```
data: {"name":"Alice","age":30}

data: {"name":"Bob","age":50}

```

```
$es->on('message', function (Clue\React\EventSource\MessageEvent $message) {
    $json = json_decode($message->data);
    echo "{$json->name} is {$json->age} years old" . PHP_EOL;
});
```

The EventSource stream may specify an event type for each incoming message. This `event` field can be used to emit appropriate event types like this:

```
data: Alice
event: join

data: Hello!
event: chat

data: Bob
event: leave

```

```
$es->on('join', function (Clue\React\EventSource\MessageEvent $message) {
    echo $message->data . ' joined' . PHP_EOL;
});

$es->on('chat', function (Clue\React\EventSource\MessageEvent $message) {
    echo 'Message: ' . $message->data . PHP_EOL;
});

$es->on('leave', function (Clue\React\EventSource\MessageEvent $message) {
    echo $message->data . ' left' . PHP_EOL;
});
```

See also [`MessageEvent::$type` property](#messageeventtype) for more details.

#### open event

[](#open-event)

The `open` event will be emitted when the EventSource connection is successfully established.

```
$es->on('open', function () {
    echo 'Connection opened' . PHP_EOL;
});
```

Once the EventSource connection is open, it may emit any number of [`message` events](#message-event).

If the connection can not be opened successfully, it will emit an [`error` event](#error-event) instead.

#### error event

[](#error-event)

The `error` event will be emitted when the EventSource connection fails. The event receives a single `Exception` argument for the error instance.

```
$es->on('error', function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
```

The EventSource connection will be retried automatically when it is temporarily disconnected. If the server sends a non-successful HTTP status code or an invalid `Content-Type` response header, the connection will fail permanently. In this case, the `error` event will receive a [`ResponseException`](https://github.com/reactphp/http#responseexception)that provides access to the response via the `getResponse()` method.

```
$es->on('error', function (Exception $e) use ($es) {
    if ($es->readyState === Clue\React\EventSource\EventSource::CLOSED) {
        echo 'Permanent error: ' . $e->getMessage() . PHP_EOL;
    } else {
        echo 'Temporary error: ' . $e->getMessage() . PHP_EOL;
    }
});
```

See also the [`EventSource::$readyState` property](#eventsourcereadystate).

#### EventSource::$readyState

[](#eventsourcereadystate)

The `int $readyState` property can be used to check the current EventSource connection state.

The state is read-only and can be in one of three states over its lifetime:

- `EventSource::CONNECTING`
- `EventSource::OPEN`
- `EventSource::CLOSED`

#### EventSource::$url

[](#eventsourceurl)

The `readonly string $url` property can be used to get the EventSource URL as given to the constructor.

#### close()

[](#close)

The `close(): void` method can be used to forcefully close the EventSource connection.

This will close any active connections or connection attempts and go into the `EventSource::CLOSED` state.

### MessageEvent

[](#messageevent)

The `MessageEvent` class represents an incoming EventSource message.

#### MessageEvent::\_\_construct()

[](#messageevent__construct)

The `new MessageEvent(string $data, string $lastEventId = '', string $type = 'message')` constructor can be used to create a new `MessageEvent` instance.

This is mostly used internally to represent each incoming message event (see also [`message` event](#message-event)). Likewise, you can also use this class in test cases to test how your application reacts to incoming messages.

The constructor validates and initializes all properties of this class. It throws an `InvalidArgumentException` if any parameters are invalid.

#### MessageEvent::$data

[](#messageeventdata)

The `readonly string $data` property can be used to access the message payload data.

```
data: hello

```

```
assert($message->data === 'hello');
```

The `data` field may also span multiple lines. This is commonly used for transporting structured data such as JSON:

```
data: {
data:     "message": "hello"
data: }

```

```
$json = json_decode($message->data);
assert($json->message === 'hello');
```

If the message does not contain a `data` field or the `data` field is empty, the message will be discarded without emitting an event.

#### MessageEvent::$lastEventId

[](#messageeventlasteventid)

The `readonly string $lastEventId` property can be used to access the last event ID.

```
data: hello
id: 1

```

```
assert($message->data === 'hello');
assert($message->lastEventId === '1');
```

Internally, the `id` field will automatically be used as the `Last-Event-ID` HTTP request header in case the connection is interrupted.

If the message does not contain an `id` field, the `$lastEventId` property will be the value of the last ID received. If no previous message contained an ID, it will default to an empty string.

#### MessageEvent::$type

[](#messageeventtype)

The `readonly string $type` property can be used to access the message event type.

```
data: Alice
event: join

```

```
assert($message->data === 'Alice');
assert($message->type === 'join');
```

Internally, the `event` field will be used to emit the appropriate event type. See also [`message` event](#message-event).

If the message does not contain a `event` field or the `event` field is empty, the `$type` property will default to `message`.

Install
-------

[](#install)

The recommended way to install this library is [through Composer](https://getcomposer.org/). [New to Composer?](https://getcomposer.org/doc/00-intro.md)

This project follows [SemVer](https://semver.org/). This will install the latest supported version:

```
composer require clue/reactphp-eventsource:^1.4
```

See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.4 through current PHP 8+. It's *highly recommended to use the latest supported PHP version* for this project.

Tests
-----

[](#tests)

To run the test suite, you first need to clone this repo and then install all dependencies [through Composer](https://getcomposer.org/):

```
composer install
```

To run the test suite, go to the project root and run:

```
vendor/bin/phpunit
```

The test suite is set up to always ensure 100% code coverage across all supported environments. If you have the Xdebug extension installed, you can also generate a code coverage report locally like this:

```
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text
```

License
-------

[](#license)

This project is released under the permissive [MIT license](LICENSE).

> Do you use this project in a commercial setting? Sponsoring with invoicing is available, contact me ([@clue](https://github.com/clue)) for details.

More
----

[](#more)

- If you want to learn more about processing streams of data, refer to the documentation of the underlying [react/stream](https://github.com/reactphp/stream) component.
- If you're looking to run the server side of your Server-Sent Events (SSE) application, you may want to use the powerful server implementation provided by [Framework X](https://framework-x.org/).

###  Health Score

51

—

FairBetter than 96% of packages

Maintenance84

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community24

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 68.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~284 days

Recently: every ~264 days

Total

6

Last Release

77d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/776829?v=4)[Christian Lück](/maintainers/clue)[@clue](https://github.com/clue)

---

Top Contributors

[![clue](https://avatars.githubusercontent.com/u/776829?v=4)](https://github.com/clue "clue (64 commits)")[![SimonFrings](https://avatars.githubusercontent.com/u/44357440?v=4)](https://github.com/SimonFrings "SimonFrings (23 commits)")[![yadaiio](https://avatars.githubusercontent.com/u/137186380?v=4)](https://github.com/yadaiio "yadaiio (3 commits)")[![boenrobot](https://avatars.githubusercontent.com/u/1029536?v=4)](https://github.com/boenrobot "boenrobot (2 commits)")[![PaulRotmann](https://avatars.githubusercontent.com/u/85174210?v=4)](https://github.com/PaulRotmann "PaulRotmann (1 commits)")

---

Tags

asyncreactphpevent-drivensseeventsourceServer-Side Events

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/clue-reactphp-eventsource/health.svg)

```
[![Health](https://phpackages.com/badges/clue-reactphp-eventsource/health.svg)](https://phpackages.com/packages/clue-reactphp-eventsource)
```

###  Alternatives

[react/socket

Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP

1.3k116.9M402](/packages/react-socket)[react/dns

Async DNS resolver for ReactPHP

535114.1M100](/packages/react-dns)[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78126.4M414](/packages/react-http)[league/geotools

Geo-related tools PHP 7.3+ library

1.4k5.3M26](/packages/league-geotools)[clue/docker-react

Async, event-driven access to the Docker Engine API, built on top of ReactPHP.

113154.9k1](/packages/clue-docker-react)[react/promise-timer

A trivial implementation of timeouts for Promises, built on top of ReactPHP.

34141.9M96](/packages/react-promise-timer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
