| Did you know ... | Search Documentation: |
| sse.pl -- Server-Sent Events (SSE) |
This library provides a small server-side helper for the Server-Sent
Events
wire format. SSE is a one-way (server to client) push channel that lives
inside a normal HTTP response with Content-Type: text/event-stream.
Each event is a sequence of Field: Value lines terminated by a blank
line.
Typical use, with the handler running on a separate thread so that the worker pool is not blocked:
:- use_module(library(http/sse)).
:- use_module(library(http/http_dispatch)).
:- http_handler(root(events), events,
[ spawn([]), time_limit(infinite) ]).
events(_Request) :-
sse_open,
between(1, infinite, Min),
sse_send(_{event: minute, data: Min}),
sleep(60),
fail.
The underlying machinery is provided by the CGI output stream, which
recognises Content-Type: text/event-stream and switches into a mode
where every flushed write is sent unbuffered to the client. The present
library hides the wire format, multi-line data handling and the
response headers needed to defeat HTTP intermediaries that buffer small
responses.
If the client disconnects, the next write raises an I/O exception that typically terminates the event-producing loop.
A single SSE response is single-writer; multiple threads writing to the same response will interleave bytes and corrupt the stream. Fan out to multiple clients by giving each connection its own writer.
Browsers loading the page from a different origin than the SSE
endpoint need Cross-Origin Resource Sharing (CORS). sse_open/0,1
calls cors_enable/0, so setting the http:cors setting (see
library(http/http_cors)) enables it.
sse_open is det
sse_open(+Options) is detevent_stream
transfer mode and each sse_send/1 or sse_send/2 is flushed to the
client. The mandatory headers emitted are:
Content-Type: text/event-streamCache-Control: no-cacheX-Accel-Buffering: no (disables nginx response buffering)
cors_enable/0 is called after the mandatory headers, so the
http:cors setting controls whether an Access-Control-Allow-Origin
header is emitted. Browser-based EventSource clients on a different
origin need this; non-browser clients do not.
Options:
Name-Value pairs. Both Name and Value are written with
format/3 using `~w`.
sse_send(+Event) is det
sse_send(+Stream, +Event) is detevent, data, id,
retry and comment. Unknown keys raise a domain_error/2.
event (atom or string) becomes one `event:` line.id (atom, string or integer) becomes one `id:` line.retry (non-negative integer) becomes one `retry:` line.comment (atom, string or list) becomes one or more :
lines (an SSE comment) before the rest of the event.data may be an atom, string, integer or list. Atoms and
strings are split on \n (with an optional \r) so that
multi-line text becomes multiple `data:` lines. A list is
taken to be a list of lines (which should not themselves
contain newlines).The empty event (a dict containing none of the recognised keys) is not allowed and raises a domain_error/2.
sse_comment(+Comment) is det
sse_comment(+Stream, +Comment) is det: lines) followed
by a blank line and flush the stream. Comments are ignored by
clients and are mainly useful as a keep-alive heartbeat through
intermediaries that close idle connections. Comment is an atom,
string or list of lines; multi-line text is split as for data.