A page usually answers once. With padSse() in its PHP it keeps the
connection open and sends events while they happen - what the browser's
EventSource reads, and what htmx's sse extension, a React or an Alpine component
listen to. There is no template: the stream is the whole answer.
<?php
// ticker.php - the producer sends the events itself
padSse ( function ( $send, $lastId ) {
foreach ( [ 'one', 'two', 'three' ] as $n => $word ) {
$send ( 'word', [ 'n' => $n, 'word' => $word ], $n );
sleep ( 1 );
}
}, [ 'retry' => 3000 ] );
?>
The browser side is a few lines, with no library:
const source = new EventSource('?ticker');
source.addEventListener('word', event => show(JSON.parse(event.data)));
Given every, PAD calls the producer itself, every so many seconds, and sends
what it answers as the event named by event: an array goes as JSON,
NULL sends nothing that round, FALSE ends the stream.
<?php
// stats.php - a fresh number every two seconds, for at most a minute
padSse ( fn () => [ 'orders' => db ( "FIELD count(*) FROM orders" ) ],
[ 'every' => 2, 'for' => 60, 'event' => 'stats' ] );
?>
| Option | Meaning |
|---|---|
every | Seconds between two calls of the producer; without it the producer is called once and loops itself |
for | How long a stream with every runs at most - 60 seconds unless said otherwise |
event | The name of the event an answer of the producer is sent as - message unless said otherwise |
retry | Milliseconds the browser waits before it reconnects when the stream ended |
$send ( $event, $data, $id ) answers whether the visitor is still
connected; a long loop stops when it says no. Text data that runs over lines goes as
several data: lines, which the browser joins again.$send ( 'done', 'done' ).padSseLastId() reads it anywhere.for short and let
the browser reconnect. Nothing of the answer is cached, compressed or buffered by PAD;
X-Accel-Buffering: no asks nginx not to hold the events back.pad pack, see
Offline applications - one PHP answers the whole tab, so a stream is one round
there: the every form calls its producer once and asks the browser back after
the interval, a FALSE with nothing sent is answered 204 and ends it, and the
loop form ends at the first event sent a tenth of a second after it began.
padWasm() says where a page runs.The htmx application streams rows of HTML that its sse extension swaps in
(htmx/?examples/live), the Alpine application JSON
an EventSource turns into state
(alpine/?examples/live).