How to know when Sse connection is closed? #1060
-
Hi, thanks a lot for axum, i much prefer it to the other rust web frameworks i have used! I want to use SSE behind authentication which necessitates storing some state for the channel/stream for each authenticated client. How would i know when the SSE connection is closed to i can remove stale state? Looking at the examples and docs didn't yield anything, hopefully i am missing something obvious, any pointers much appreciated 🙏 |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
You can make a type that implements async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
struct Guard {
// whatever state you need here
}
impl Drop for Guard {
fn drop(&mut self) {
tracing::info!("stream closed");
}
}
let stream = async_stream::stream! {
let _guard = Guard {};
let mut interval = tokio::time::interval(Duration::from_secs(1));
loop {
interval.tick().await;
yield Ok(Event::default().data("hi"));
}
// `_guard` is dropped
};
Sse::new(stream)
} |
Beta Was this translation helpful? Give feedback.
-
Unfortunately @davidpdrsn, this does not appear to work. I created an MVP to reproduce the issue here: https://github.com/tmpfs/axum-sse-close-mvp. The client correctly closes the event source but the server does not execute the code after the Am I doing something wrong or any other ideas on how to detect the stream close event? Scrap that I wasn't putting the drop in place, sorry! |
Beta Was this translation helpful? Give feedback.
-
Thanks @davidpdrsn! Exactly what I needed for cleanup tasks on stream closure. |
Beta Was this translation helpful? Give feedback.
-
In case anyone might find it useful, the suggested solution didnt apply to me as i was wrapping a receiver in a stream instead of wrapping a loop or tokio task. So i found that you can create a new tokio task to listen and wait for the transmitter to be closed.
Seems to be working for me, not sure if im not seeing something in how it could not work. |
Beta Was this translation helpful? Give feedback.
You can make a type that implements
Drop
and hold that until the stream closes. Doing that with async-stream is quite easy: