A job's events as Server-Sent Events (text/event-stream), read as they come: what JobController's events.sse answers, through a StreamResponse (which sends each chunk as it is read).
class MMO\core\jobs\JobEventStream
implements Psr\Http\Message\StreamInterface
Espace de noms
MMO\core\jobs
Implémente
StreamInterface
Each event of the job ([`JobStore::events`](https://mmoframework.fr/documentation/mmo.core/php/jobs/JobStore.md#jobstore-events)) becomes one frame: `id:` its position, `event:` its type, `data:` its
json. A browser's `EventSource` sends the last id back when it reconnects (`Last-Event-ID`), and the stream starts
after it: nothing is lost or repeated. The stream:
- starts with `retry:` (how long a browser waits before reconnecting) and a `job` frame, the job's record;
- waits for new events, checking every [`$interval`](https://mmoframework.fr/documentation/mmo.core/php/jobs/JobEventStream.md#jobeventstream-interval) seconds, with a comment every [`$keepAlive`](https://mmoframework.fr/documentation/mmo.core/php/jobs/JobEventStream.md#jobeventstream-keepalive) seconds so
that no proxy closes it;
- releases the session (its lock would block every other request of the browser while it streams);
- ends once the job has ended and its last event is sent (an `end` frame, the record again: a browser then closes
its `EventSource`, or it would reconnect), when the client leaves, or after [`$duration`](https://mmoframework.fr/documentation/mmo.core/php/jobs/JobEventStream.md#jobeventstream-duration) seconds (the browser
reconnects where it stopped: a php worker is not held forever).
$stream = new JobEventStream(JobStore::Shared(), $id, (int)($_SERVER['HTTP_LAST_EVENT_ID'] ?? 0));
return new StreamResponse($stream, 200, 'OK', JobEventStream::Headers());