roadrunner_gleam/push
Responses that stay open and push data as messages arrive, such as server-sent events.
The response’s headers go out first, then whatever on_init sends.
After that the handler runs for every message sent to the Subject
that on_init got, or selected with with_selector, and sends data to
the client, until it stops or the client goes away. It works the same
over HTTP/1.1, HTTP/2 and HTTP/3. A HEAD request gets the headers
only, and on_init is not called.
fn events(request: Request) -> Response {
push.new(
on_init: fn(subject) {
pubsub.subscribe(subject)
push.continue(Nil)
|> push.send_event(push.event("connected") |> push.event_retry(5000))
},
handler: fn(state, message) {
case message {
push.Custom(text) ->
push.continue(state) |> push.send_event(push.event(text))
push.Draining(_) -> push.stop(state)
}
},
)
|> push.response(200)
|> http_response.set_header("content-type", "text/event-stream")
}
Types
A response that pushes, built with new and the functions that follow
it.
pub opaque type Builder(state, custom)
A server-sent event, built with event and the functions that follow
it.
pub opaque type Event
What the handler gets.
pub type Message(custom) {
Custom(custom)
Draining(remaining: Int)
}
Constructors
-
Custom(custom)A message sent to the
Subjectthaton_initgot, or one selected bywith_selector. -
Draining(remaining: Int)The listener is draining: stop within
remainingmilliseconds, or the response is closed for you.
Values
pub fn event(data: String) -> Event
A server-sent event with this data. Data with line breaks is sent as
several data: lines, which the browser joins back.
pub fn event_id(event: Event, id: String) -> Event
The event’s id, which the browser sends back as last-event-id when it
reconnects.
pub fn event_name(event: Event, name: String) -> Event
The event’s name: the browser’s EventSource delivers it to the
listeners of that name instead of onmessage.
pub fn event_retry(event: Event, milliseconds: Int) -> Event
How many milliseconds the browser waits before reconnecting.
pub fn event_to_bytes(event: Event) -> bytes_tree.BytesTree
The event as it goes on the wire.
pub fn new(
on_init on_init: fn(process.Subject(custom)) -> Next(
state,
custom,
),
handler handler: fn(state, Message(custom)) -> Next(
state,
custom,
),
) -> Builder(state, custom)
A response that pushes. on_init runs once, before the headers go out,
and gets a Subject owned by the response: messages sent to it reach
handler as Custom. What it sends goes out right after the headers.
pub fn on_disconnect(
builder: Builder(state, custom),
on_disconnect: fn(state) -> Nil,
) -> Builder(state, custom)
Run on_disconnect when the client goes away before the handler
stops, to drop subscriptions and stop work.
pub fn response(
builder: Builder(state, custom),
status: Int,
) -> response.Response(response.Body)
The response, with this status. Add headers with
gleam/http/response.set_header.
pub fn send(
next: Next(state, custom),
data: bytes_tree.BytesTree,
) -> Next(state, custom)
Send this data to the client after the callback.
pub fn send_event(
next: Next(state, custom),
event: Event,
) -> Next(state, custom)
Send a server-sent event to the client after the callback.
pub fn stop(state: state) -> Next(state, custom)
End the response, after sending what was given to send.
pub fn with_selector(
next: Next(state, custom),
selector: process.Selector(custom),
) -> Next(state, custom)
Also receive the messages this selector selects, as Custom, from now
on: monitors, messages to other subjects, or anything else. It replaces
the selector set before; messages to the response’s Subject always
arrive.