mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-15 00:00:20 +02:00
This reworks axum's docs in an attempt to make things easier to find. Previously I wasn't a fan of those docs for the same topic were spread across the root module docs and more specific places like types and methods. This changes it such that the root module docs only gives a high level introduction to a topic, perhaps with a small example, and then link to other places where all the details are. This means `Router` is now the single place to learn about routing, and etc for the topics like handlers and error handling.
64 lines
1.9 KiB
Rust
64 lines
1.9 KiB
Rust
//! Run with
|
|
//!
|
|
//! ```not_rust
|
|
//! cargo run -p example-sse
|
|
//! ```
|
|
|
|
use axum::{
|
|
error_handling::HandleErrorExt,
|
|
extract::TypedHeader,
|
|
http::StatusCode,
|
|
response::sse::{Event, Sse},
|
|
routing::{get, service_method_routing as service},
|
|
Router,
|
|
};
|
|
use futures::stream::{self, Stream};
|
|
use std::{convert::Infallible, net::SocketAddr, time::Duration};
|
|
use tokio_stream::StreamExt as _;
|
|
use tower_http::{services::ServeDir, trace::TraceLayer};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
// Set the RUST_LOG, if it hasn't been explicitly defined
|
|
if std::env::var_os("RUST_LOG").is_none() {
|
|
std::env::set_var("RUST_LOG", "example_sse=debug,tower_http=debug")
|
|
}
|
|
tracing_subscriber::fmt::init();
|
|
|
|
let static_files_service =
|
|
service::get(ServeDir::new("examples/sse/assets").append_index_html_on_directories(true))
|
|
.handle_error(|error: std::io::Error| {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Unhandled internal error: {}", error),
|
|
)
|
|
});
|
|
|
|
// build our application with a route
|
|
let app = Router::new()
|
|
.fallback(static_files_service)
|
|
.route("/sse", get(sse_handler))
|
|
.layer(TraceLayer::new_for_http());
|
|
|
|
// run it
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
|
tracing::debug!("listening on {}", addr);
|
|
axum::Server::bind(&addr)
|
|
.serve(app.into_make_service())
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
async fn sse_handler(
|
|
TypedHeader(user_agent): TypedHeader<headers::UserAgent>,
|
|
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
|
|
println!("`{}` connected", user_agent.as_str());
|
|
|
|
// A `Stream` that repeats an event every second
|
|
let stream = stream::repeat_with(|| Event::default().data("hi!"))
|
|
.map(Ok)
|
|
.throttle(Duration::from_secs(1));
|
|
|
|
Sse::new(stream)
|
|
}
|