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.