Skip to main content

Server-Sent Events (SSE)

Server-sent events (SSE) let a server send updates to a client over a long-lived HTTP response. Use SSE for notifications, progress updates, or live feeds. Communication is one-way: the server sends events to the client. For two-way communication, see WebSockets.

Actix Web supports SSE through the sse module in the actix-web-lab crate. Its Sse responder sets the text/event-stream content type and formats events for the client.

Send Events​

Create an Sse responder from a stream with Sse::from_stream(), or from a Tokio channel receiver with Sse::from_infallible_receiver(). Use Data to create messages. Each message can include an event name and an ID.

For a long-lived connection, use with_keep_alive() to send periodic comments while no events are available. Use with_retry_duration() to set the client's reconnection delay.

Add these dependencies to your Cargo.toml:

[dependencies]
actix-web = "4"
actix-web-lab = "0.29"
tokio = { version = "1", features = ["sync"] }

This server sends an unnamed message immediately and then every five seconds. The task stops when the client disconnects and the channel closes.

use std::time::Duration;

use actix_web::{App, HttpServer, Responder, rt, web};
use actix_web_lab::sse;
use tokio::sync::mpsc;

async fn events() -> impl Responder {
let (tx, rx) = mpsc::channel(10);

rt::spawn(async move {
let mut interval = rt::time::interval(Duration::from_secs(5));

loop {
interval.tick().await;

if tx
.send(sse::Data::new("Hello from Actix Web!").into())
.await
.is_err()
{
break;
}
}
});

sse::Sse::from_infallible_receiver(rx)
.with_keep_alive(Duration::from_secs(15))
.with_retry_duration(Duration::from_secs(3))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/events", web::get().to(events)))
.bind(("127.0.0.1", 8080))?
.run()
.await
}

See the SSE API examples for more handlers. A complete broadcast example is available in the examples repository.

Receive Events in a Browser​

Use the browser's EventSource API to connect to an SSE endpoint:

const events = new EventSource("/events");

events.onmessage = (event) => {
console.log(event.data);
};

Replace /events with your endpoint's path. The message handler receives events that have no event name. For named events, use addEventListener() with the matching name:

events.addEventListener("chat_msg", (event) => {
console.log(event.data);
});

The browser reconnects automatically if the connection closes. Call events.close() when updates are no longer needed. Event IDs let the browser send a Last-Event-ID header when it reconnects; your application must handle that ID if it needs to replay missed events.