lilydocs
HTTP APIWebSocketConsumer
Techniques2 min read

Server-Sent Events

Stream events to the browser and design backpressure and reconnection behavior.

SSE sends events to a browser over a single HTTP response. SseEvent provides the event format, and SseResponse provides the lazy response.

Your first event#

Add futures = "0.3" to your manifest. Import std::convert::Infallible and the facade's sse, SseEvent, and SseResponse. An action in the /files controller:

Controller action snippet
#[get("/events")]
async fn events(&self) -> Result<SseResponse, HttpApiError> {
    let event = SseEvent::new("export-ready")?
        .event("export")?
        .id("1")?;
    Ok(sse(futures::stream::iter([Ok::<_, Infallible>(event)])))
}
Observing the event stream
curl -N http://127.0.0.1:8080/files/events

This example produces one event named export with ID 1, then completes. The complete controller example also includes the other streaming paths.

Continuous event production#

sse_channel(capacity) creates a bounded channel. send applies backpressure; try_send reports when the channel is full. Observe consumer closure through closed. Decide how the producer responds to a slow consumer instead of allowing queue capacity to grow without bounds.

Reconnection#

RequestExt::last_event_id reads the client's cursor. Storing and replaying past events is the application's responsibility. Reading a cursor alone does not guarantee lossless reconnection.

Keep-alive and deadlines#

Event data, event names, IDs, and retry fields are validated. Choosing keep-alive/heartbeats helps keep the connection active; it does not renew the request deadline. SSE remains subject to transport timeouts and shutdown rules.

A producer started with your own tokio::spawn call does not automatically become a worker managed by the HTTP host. Define producer resource ownership explicitly or use the background service model.

Sources for this page v0.1.0

This guide is based on the reviewed framework commit.

QUICK START
Documentation
Source code