Download the PHP package freddie/mercure-x without Composer
On this page you can find all versions of the php package freddie/mercure-x. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package mercure-x
Freddie
Freddie is a PHP implementation of the Mercure Hub Specification.
It is blazing fast, built on the shoulders of giants:
- PHP 8.1
- Framework X and ReactPHP
- Symfony 6
- Redis (optionally).
See what features are covered and what aren't (yet) here.
Installation
PHP 8.1+ is required to run the hub.
As a standalone Mercure hub
This will start a Freddie instance on 127.0.0.1:8080, with anonymous subscriptions enabled.
You can publish updates to the hub by generating a valid JWT signed with the !ChangeMe! key with HMAC SHA256 algorithm.
To change these values, see Security.
As a bundle of your existing Symfony application
You can then start the hub by doing:
You can override relevant env vars in your .env.local
and services in your config/services.yaml as usual.
Then, you can inject Freddie\Hub\HubInterface in your services so that you can call $hub->publish($update),
or listening to dispatched updates in a CLI context 👍
Keep in mind this only works when using the Redis transport.
⚠️ Freddie uses its own routing/authentication system (because of async / event loop).
The controllers it exposes cannot be imported in your routes.yaml, and get out of your security.yaml scope.
Usage
It will start a new Mercure hub on 127.0.0.1:8080.
To change this address, use the X_LISTEN environment variable:
Security
The default JWT key is !ChangeMe! with a HS256 signature.
You can set different values by changing the environment variables (in .env.local or at the OS level):
X_LISTEN, JWT_SECRET_KEY, JWT_ALGORITHM, JWT_PUBLIC_KEY and JWT_PASSPHRASE (when using RS512 or ECDSA)
Please refer to the authorization section of the Mercure specification to authenticate as a publisher and/or a subscriber.
PHP Transport (default)
By default, the hub will run as a simple event-dispatcher, in a single PHP process.
It can fit common needs for a basic usage, but using this transport prevents scalability, as opening another process won't share the same event emitter.
It's still prefectly usable as soon as :
- You don't expect more than a few hundreds updates per second
- Your application is served from a single server.
Redis transport
On the other hand, you can launch the hub on multiple ports and/or multiple servers with a Redis transport (as soon as they share the same Redis instance), and optionally use a load-balancer to distribute the traffic.
The official open-source version of the hub doesn't allow scaling because of concurrency restrictions on the bolt transport.
To launch the hub with the Redis transport, change the TRANSPORT_DSN environment variable:
Optional parameters you can pass in the DSN's query string:
pingInterval- regularly ping Redis connection, which will help detect outages (default2.0)readTimeout- max duration in seconds of a ping or publish request (default0.0: considered disabled)
Alternatively, you can set this variable into .env.local.
Advantages and limitations
This implementation does not provide SSL nor HTTP2 termination, so you'd better put a reverse proxy in front of it.
Example Nginx configuration
Example Caddy configuration
Single node
With multiple nodes
Payload limitations
⚠ There's a known limit in Framework-X which prevents request bodies to weigh more than 64 KB. At the time of writing, this limit cannot be raised due to Framework-X encapsulating HTTP Server instantiation.
Publishing bigger updates to Freddie (through HTTP, at least) could result in 400 errors.
Feature coverage
| Feature | Covered |
|---|---|
JWT through Authorization header |
✅ |
JWT through mercureAuthorization Cookie |
✅ |
| Allow anonymous subscribers | ✅ |
| Alternate topics | ✅️ |
| Private updates | ✅ |
| URI Templates for topics | ✅ |
| HMAC SHA256 JWT signatures | ✅ |
| RS512 JWT signatures | ✅ |
| Environment variables configuration | ✅ |
| Custom message IDs | ✅ |
Last event ID (including earliest) |
✅️ |
| Customizable event type | ✅️ |
Customizable retry directive |
✅️ |
| CORS | ❌ (configure them on your web server) |
| Health check endpoint | ❌ (PR welcome) |
| Logging | ❌ (PR welcome))️ |
| Metrics | ❌ (PR welcome)️ |
| Different JWTs for subscribers / publishers | ❌ (PR welcome) |
| Subscription API | ❌️ (TODO) |
Tests
This project is 100% covered with Pest tests.
Contribute
If you want to improve this project, feel free to submit PRs:
- CI will yell if you don't follow PSR-12 coding standards
- In the case of a new feature, it must come along with tests
- PHPStan analysis must pass at level 8
You can run the following command before committing to ensure all CI requirements are successfully met:
License
GNU General Public License v3.0.
All versions of mercure-x with dependencies
ext-ctype Version *
ext-iconv Version *
bentools/querystring Version ^1.1
clue/framework-x Version dev-main#cfe017426d8acc7a92b5893a501728e034a873cc
clue/redis-react Version ^2.5
doctrine/annotations Version ^1.0
lcobucci/jwt Version ^5.5
nyholm/dsn Version ^2.0
phpdocumentor/reflection-docblock Version ^5.3
react/async Version ^4.0.0
react/promise-timer Version ^1.10
rize/uri-template Version ^0.4.1
symfony/clock Version ^6.0|^7.0.0|^8.0.0
symfony/console Version ^6.0.0|^7.0.0|^8.0.0
symfony/deprecation-contracts Version ^3.1
symfony/dotenv Version ^6.0.0|^7.0.0|^8.0.0
symfony/flex Version ^1.17|^2
symfony/framework-bundle Version ^6.0.0|^7.0.0|^8.0.0
symfony/options-resolver Version ^6.0.0|^7.0.0|^8.0.0
symfony/property-access Version ^6.0.0|^7.0.0|^8.0.0
symfony/property-info Version ^6.0.0|^7.0.0|^8.0.0
symfony/runtime Version ^6.0.0|^7.0.0|^8.0.0
symfony/uid Version ^6.0.0|^7.0.0|^8.0.0
symfony/yaml Version ^6.0.0|^7.0.0|^8.0.0