Connected the websocket to the state
This commit is contained in:
51
src/main.rs
51
src/main.rs
@@ -1,12 +1,13 @@
|
||||
mod simulation;
|
||||
mod state;
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::sync::Arc;
|
||||
use std::{convert::Infallible, sync::Arc};
|
||||
|
||||
use futures::SinkExt;
|
||||
use serde_json::json;
|
||||
use tera::{Context, Tera};
|
||||
use tokio::sync::watch;
|
||||
use warp::Filter;
|
||||
use warp::{Filter, ws::{Message, WebSocket}};
|
||||
|
||||
use simulation::Simulation;
|
||||
use state::State;
|
||||
@@ -29,26 +30,58 @@ async fn main() {
|
||||
}
|
||||
};
|
||||
let tr = Arc::new(tr);
|
||||
let tera = move |with_template| render(with_template, tr.clone());
|
||||
let tera = move || {
|
||||
let tr = tr.clone();
|
||||
move |with_template| render(with_template, tr.clone())
|
||||
};
|
||||
let state = move || {
|
||||
let state_channel = state_channel.clone();
|
||||
move || state_channel.clone()
|
||||
};
|
||||
|
||||
let sim = tokio::spawn(async move {
|
||||
simulation.run().await;
|
||||
});
|
||||
|
||||
let hello = warp::get().and(warp::path::end())
|
||||
.map(move || (state_channel.clone()))
|
||||
let hello = warp::get()
|
||||
.and(warp::path::end())
|
||||
.map(state())
|
||||
.and_then(|channel| async move { get_state(channel).await })
|
||||
.map(|state| WithTemplate {
|
||||
name: "stuff.tera",
|
||||
context: Context::from_serialize(state).unwrap()
|
||||
context: Context::from_serialize(state).unwrap(),
|
||||
})
|
||||
.map(tera);
|
||||
.map(tera());
|
||||
|
||||
let server = tokio::spawn(async move { warp::serve(hello).run(([127, 0, 0, 1], 3030)).await });
|
||||
let wsstate = state();
|
||||
let ws = warp::path("state")
|
||||
.and(warp::ws())
|
||||
.map(move |ws: warp::ws::Ws| (ws, wsstate()))
|
||||
.map(|(ws, state): (warp::ws::Ws, watch::Receiver<State>)| {
|
||||
ws.on_upgrade(move |websocket| watch_state(websocket, state))
|
||||
});
|
||||
|
||||
let server =
|
||||
tokio::spawn(async move { warp::serve(hello.or(ws)).run(([127, 0, 0, 1], 3030)).await });
|
||||
|
||||
tokio::try_join!(sim, server).unwrap();
|
||||
}
|
||||
|
||||
async fn watch_state(mut ws: WebSocket, mut state_channel: watch::Receiver<State>) {
|
||||
loop {
|
||||
let state = state_channel.recv().await;
|
||||
|
||||
let result = match state {
|
||||
Some(state) => ws.send(Message::text(json!(state).to_string())).await,
|
||||
None => ws.send(Message::text("Oh...")).await,
|
||||
};
|
||||
|
||||
if let Err(_) = result {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async fn get_state(mut channel: watch::Receiver<State>) -> Result<State, Infallible> {
|
||||
Ok(channel.recv().await.unwrap())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user