raneomik / nette-mercure
🚀 Nette Mercure Extension: nette wrapper around https://github.com/symfony/mercure
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/raneomik/nette-mercure
Requires
- php: >=8.4
- ext-tokenizer: *
- lcobucci/jwt: 6.0.x-dev
- nette/http: ^2.0|^3.3
- symfony/mercure: ^0.7.2
Requires (Dev)
- latte/latte: ^2.0|^3.0
- nette/application: ^4.0@dev
- nette/di: ^3.0
- nette/security: ^3.0
- nette/tester: ^2.5@dev
- phpro/grumphp: v2.x-dev
- phpstan/phpstan-nette: ^2.0@stable
- rector/rector: ^2.3.4
- symplify/easy-coding-standard: ^13.0
- tracy/tracy: ^2.8
README
🚀 Nette Mercure Extension: wrapper for symfony/mercure to use Mercure in Nette framework
Mercure is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. It is especially useful to publish real-time updates of resources served through web APIs, to reactive web and mobile apps.
Getting Started
$ composer require nette/mercure
Configuration
JWT options to set. Secret, publish & subscribe can be configured at jwt.io
# Configure one default Mercure hub (default hub on same host in frankenphp environment) mercure: url: '%baseUrl%/.well-known/mercure' jwt: secret: n3tt3-m3rcµr3-fr4nk3nphP-jwT-s3cr3t-k3y # Must be at least 32 characters long publish: ['test-topic'] # Optional, default is ['*']. Allow topics for which this JWT can be used to publish updates. subscribe: ['test-topic'] # Optional, default is ['*']. Allow topics for which this JWT can be used to subscribe to updates. algorithm: HS256 # Optional, default is HS256. @see Symfony\Component\Mercure\Jwt\LcobucciFactory::SIGN_ALGORITHMS # You can implement your own Symfony\Component\Mercure\Jwt\TokenFactoryInterface factory: # Optional, default is Symfony\Component\Mercure\Jwt\LcobucciFactory # several Mercure hubs mercure: one url: 'https://hub1.mercure.dev/.well-known/mercure' jwt: secret: n3tt3-m3rcµr3-fr4nk3nphP-jwT-s3cr3t-k3y two url: 'https://hub2.mercure.dev/.well-known/mercure' jwt: secret: n3tt3-m3rcµr3-fr4nk3nphP-jwT-s3cr3t-k3y # ...
Sending messages
use Raneomik\NetteMercure\BroadcasterInterface; use Raneomik\NetteMercure\Latte\TurboStream\Action; final class SomeService { public function __construct( private BroadcasterInterface $broadcaster, ) { } public function someAction(): void { // ... // minimalist broadcast to default hub $this->broadcaster->broadcast( data: 'Hello Nette from Mercure!', // ['message' => 'message'] / new Class('message') topics: 'test-topic' // ['test-topic'], ); // broadcast to specific hub $this->broadcaster->broadcast( data: 'Hello Nette from Mercure!', topics: ['test-topic'], template: 'test.latte', // existing template options: [ 'hub' => 'two' ], ); // broadcast to all hubs $this->broadcaster->broadcast( data: 'Hello Nette from Mercure!', topics: ['test-topic'], template: 'test.stream.latte', options: [ 'action' => Action::Update // for turbo streams or block organisation in same template. Template must have Action blocks ], toAll: true, ); // ... } }
Listening to updates
Setup your JavaScript client to listen to Mercure updates and render them in selected containers.
// assets/main.js - import a Mercure client sample import './../vendor/raneomik/nette-mercure/assets/js/mercure-client.js'; // or implement your own Mercure client - here's a minimalistic template/example: const eventSource = new EventSource(/*mercureUrl*/); const containers = /* select containers for mercure updates to render */; eventSource.onmessage = event => { for (const container of containers) { container.textContent = event.data; } } ...
Use it in Latte templates:
<!-- ... --> <!-- use mercure(array|string|null $topics, ?string $hub = null) function to render mercure URL --> <div data-mercure-url="{mercure('test-topic')}" data-mercure="test-topic">Waiting for updates...</div> <!-- ... --> ...
Resources
- Mercure
- Documentation
- wrapped symfony/mercure
Known issues
"anonymous" option for mercure in Caddy configuration seems to work only with Symfony\Mercure\FrankenPhpHub and the FrankenPHP built-in mercure_publish function.
HttpClient shows errors such as "405 Method Not Allowed" in this case.
Authentication cookie for mercure should be implemented soon.